Skip to content

Cannot change the limits of a model #53005

Closed

Description

@litoj

Description

when filling out the limit field of any model, the provider of that model just disappears entirely.

Plugins

No response

OpenCode version

2.0.22

Steps to reproduce

	"provider": {
		"e-infra": {
			"npm": "@ai-sdk/openai-compatible",
			"name": "E-Infra",
			"options": {
				"baseURL": "https://llm.ai.e-infra.cz/v1"
			},
			"models": {
				"thinker": {
					"name": "thinker",
					"limit": {
						"context": 1000000
					}
				}
}}}

open opencode

Screenshot and/or share link

No limits field:
Image

anything set to the limits field: (empty table / number / configured table - just anything)

Image

Operating System

Archlinux 1.0

Terminal

foot

Activity

  1. github-actions commented on Oct 3, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. litoj commented on Oct 3, 2026

    @litoj
    Author

    apparently it works only if all input, context and output are defined

  3. opencodejr commented on Oct 27, 2026

    @opencodejr

    Thanks for the clear report. I could reproduce this on 2.0.22, and it still happens on the latest dev (45b53fe6f).

    What I saw, using your legacy-style config (provider / npm / options):

    • If a model's limit sets only context (or is {}), the whole provider is dropped with no error. opencode debug config shows the provider list as empty, and the provider's models are missing from /models.
    • The same provider without limit is listed normally.
    • In my tests, a limit with both context and output (e.g. "limit": { "context": 1000000, "output": 8192 }) kept the provider and applied the limit. Until this is fixed, setting both may work around it for you.

    The recording and script below load three otherwise identical providers. Only the one whose model has a context-only limit is missing from the model list.

    You mentioned that a complete limits table also made the provider disappear, which I couldn't reproduce. While testing, I noticed the background service sometimes kept the previous config after I edited the file, until I ran opencode service stop. That may be what you saw. If a full context + output limit still hides the provider after restarting the service, please post that exact config here.

    Related: the open PR #53129 targets this issue.

    recording.mp4

    Screenshot

    Reproduction script (drive.ts)
    // Repro for anomalyco/opencode#53005: a legacy-format custom provider whose model
    // sets only `limit.context` disappears from the model list. The same provider
    // without `limit` (or with both context and output) is listed.
    import { Effect } from "effect"
    import { OpenCodeDriver } from "opencode-drive"
    
    const provider = (name: string, model: string, limit?: object) => ({
      npm: "@ai-sdk/openai-compatible",
      name,
      options: { baseURL: "https://llm.ai.e-infra.cz/v1", apiKey: "dummy" },
      models: { thinker: { name: model, ...(limit ? { limit } : {}) } },
    })
    
    export default OpenCodeDriver.use(
      {
        ...(process.env.OC_DEV ? { opencode: { dev: process.env.OC_DEV } } : {}),
        tui: { recording: true, keypressOverlay: true },
        setup: ({ config }: any) =>
          Effect.sync(() => {
            config.provider = {
              "no-limit": provider("NoLimit Provider", "thinker-no-limit"),
              "full-limit": provider("FullLimit Provider", "thinker-full-limit", { context: 1000000, output: 8192 }),
              "e-infra": provider("E-Infra", "thinker-context-only-limit", { context: 1000000 }),
            }
          }),
      } as any,
      ({ ui }) =>
        Effect.gen(function* () {
          yield* Effect.sleep("2 seconds")
          yield* ui.submit("/models")
          yield* Effect.sleep("1 second")
          yield* ui.type("thinker")
          yield* Effect.sleep("2 seconds")
          yield* ui.screenshot("models-thinker")
          const frame: any = yield* ui.capture()
          const text = typeof frame === "string" ? frame : JSON.stringify(frame)
          yield* Effect.log(`NoLimit listed: ${text.includes("thinker-no-limit")}`)
          yield* Effect.log(`FullLimit listed: ${text.includes("thinker-full-limit")}`)
          yield* Effect.log(`E-Infra (context-only limit) listed: ${text.includes("thinker-context-only-limit")}`)
          yield* Effect.sleep("1 second")
        }),
    )

    Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions