Skip to content

init: cryptic SyntaxError when any existing config JSON is malformed — report the exact file path #17

Description

@BEEugene

Bug

opencode-rag init aborts with an unhelpful error if any of the existing config files in the workspace contains invalid JSON. The error message does not indicate which file caused the problem, forcing the user to bisect the project to find the offender.

Reproduction

  1. Create a workspace with an existing .opencode/opencode.json (or .opencode/tui.json / .opencode/package.json) that contains invalid JSON (e.g. a trailing comma).
  2. From that workspace run opencode-rag init.
  3. The command crashes and there is no indication of which file is broken.

Actual error (latest version)

In the current release the underlying SyntaxError is now caught and re-thrown as Init failed:, but the offending file path is still missing — only the byte position is reported:

Init failed: Expected double-quoted property name in JSON at position 480 (line 20 column 7)

In earlier versions the same problem surfaced as a raw, unhandled V8 error with a full stack:

SyntaxError: Expected double-quoted property name in JSON at position 480 (line 20 column 7)
    at JSON.parse (<anonymous>)
    at readJsonObject (file:///.../opencode-rag-plugin/dist/cli.js:100:17)
    at Command.<anonymous> (file:///.../opencode-rag-plugin/dist/cli.js:1039:52)

Either way, the user is left guessing which of the three config files (or the project-level opencode-rag.json) is the culprit.

Root cause

In dist/cli.js, the init action calls readJsonObject(...) for three workspace files:

  • cli.js:1039.opencode/opencode.json
  • cli.js:1083.opencode/tui.json
  • cli.js:1111.opencode/package.json

The raw call re-throws a SyntaxError that carries a byte offset and (line, column), but no file path. The outer Init failed: wrapper only prefixes the message — it does not enrich it with context. Only the global config cleanup at cli.js:154 is wrapped in try/catch; the init path is not.

Suggested fix

Wrap each readJsonObject call in init with try/catch and prepend the offending file path to the error message before re-throwing, e.g.:

let cfg;
try {
    cfg = readJsonObject(opencodeConfigPath);
} catch (err) {
    throw new Error(`Failed to parse ${opencodeConfigPath}: ${err.message}`);
}

Applying the same change at lines 1039, 1083 and 1111 will give users a clear, actionable error like Failed to parse D:\path\to\.opencode\opencode.json: ... instead of a position-only stack trace. Bonus: if you also include the file path in the existing Init failed: wrapper, both old and new surfaces benefit from a single point of fix.

Environment

  • OS: Windows 10/11
  • Node.js: any modern LTS
  • Plugin version: latest npm (current Init failed: wrapper is present)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions