Skip to content

fix(core): substitute empty for missing config file references - #55388

Merged
neriousy merged 1 commit into
devfrom
missing-file-reference
Oct 14, 2026
Merged

neriousy merged 1 commit into
devfrom
missing-file-reference

Conversation

@neriousy

Copy link
Copy Markdown
Member

Issue for this PR

Closes #

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

A {file:...} reference to a missing file (e.g. a deleted secret in an MCP Authorization header) failed config loading with ConfigInvalidError. Config.load turns that into a defect, so every Location that loads the config failed to boot. For the global config that is every directory: the server returned an empty-body 500 on all location-scoped routes, the TUI exited before rendering, and the desktop app came up with no models/providers/agents and only "UnexpectedStatus: 500" toasts.

A missing or unreadable referenced file now substitutes an empty string and logs a warning, matching how a missing {env:VAR} already behaves and how a missing/unreadable config file is treated (readFileStringSafe). Only the affected value breaks (e.g. that one MCP server gets a 401). Other read failures, such as a reference pointing at a directory, still fail as before.

Also removes the unused missing option from ConfigVariable.substitute.

How did you verify your code works?

  • Extended the existing substitution test with a missing ~/ reference inside an MCP header; it fails on dev and passes here.
  • Tests that used a missing reference as a "broken config" fixture (location-layer, session-move) now point the reference at a directory, which is still fatal, so they keep covering the failure/repair paths.
  • bun test test/config test/location-layer.test.ts test/session-move.test.ts and bun typecheck in packages/core.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks sound. I reproduced the failure on dev: a global config whose MCP header uses {file:~/missing} made GET /api/config?location[directory]=… return an empty-body 500. With this branch the same request returns 200, the header is substituted as "Bearer ", and the new warning shows up in the log. The config, location-layer and session-move tests pass (277 pass, 0 fail), and packages/core typechecks.

readFileStringSafe only absorbs NotFound/PermissionDenied errors, so other read failures, such as a reference to a directory, still fail the load. The updated fixtures use exactly that case, so the failure and repair paths are still covered.

Public API: no schema keys, routes, SDK or plugin surfaces change. The only visible difference is behavioural: a missing or unreadable {file:…} now becomes an empty string instead of a ConfigInvalidError. That is backwards compatible, since every config that loaded before still loads the same way.

No blocking concerns.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant