{"record":{"id":"c9d5ba6cb4044850","repo":"different-ai/openwork","slug":"constants-json-is-missing-opencodeversion","errorCode":null,"errorMessage":"constants.json is missing opencodeVersion","messagePattern":"constants\\.json is missing opencodeVersion","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/runtime.mjs","lineNumber":1773,"sourceCode":"      found: true,\n      inPath: resolved.source === \"path\",\n      resolvedPath: resolved.path,\n      resolvedSource: resolved.source,\n      version: versionResult.stdout?.trim() || versionResult.stderr?.trim() || null,\n      supportsServe: helpResult.status === 0,\n      notes,\n      serveHelpStatus: typeof helpResult.status === \"number\" ? helpResult.status : null,\n      serveHelpStdout: helpResult.stdout?.trim() || null,\n      serveHelpStderr: helpResult.stderr?.trim() || null,\n    };\n  }\n\n  async function pinnedOpencodeInstallCommand() {\n    const constantsPath = path.resolve(desktopRoot, \"../../constants.json\");\n    const payload = JSON.parse(await readFile(constantsPath, \"utf8\"));\n    const version = String(payload?.opencodeVersion ?? \"\").trim().replace(/^v/, \"\");\n    if (!version) {\n      throw new Error(\"constants.json is missing opencodeVersion\");\n    }\n    return `curl -fsSL https://opencode.ai/install | bash -s -- --version ${version} --no-modify-path`;\n  }\n\n  function processMatchesSidecar(command) {\n    return commandMatchesPackagedSidecar(command, sidecarDirs);\n  }\n\n  function killProcessId(pid, signal = \"SIGTERM\") {\n    if (!Number.isFinite(pid) || pid <= 0 || pid === process.pid) return;\n    try {\n      process.kill(pid, signal);\n    } catch {\n      // Process already exited or is not ours.\n    }\n  }\n\n  async function cleanupPackagedSidecars() {","sourceCodeStart":1755,"sourceCodeEnd":1791,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/runtime.mjs#L1755-L1791","documentation":"pinnedOpencodeInstallCommand() reads the repo-root constants.json to find the pinned opencode version used when installing OpenCode. If the JSON parses but has no non-empty `opencodeVersion` field, this error is thrown because no install command can be constructed. It indicates a broken or outdated constants.json in the desktop workspace.","triggerScenarios":"constants.json at desktopRoot/../../constants.json exists and parses as JSON, but `payload.opencodeVersion` is undefined, null, an empty string, or only whitespace (e.g. \"\" or \"v\").","commonSituations":"A fresh checkout or generated constants.json that omits opencodeVersion; a manual edit or merge that removed the key; a version-pinning script that wrote an empty value; a typo like `openCodeVersion` in the JSON.","solutions":["Add or restore `\"opencodeVersion\": \"x.y.z\"` in constants.json at the repo root.","Verify the key name is exactly `opencodeVersion` (camelCase) and its value is a non-empty version string (leading `v` is stripped automatically).","Re-run the repo's constants/update script that normally generates constants.json.","Commit a valid constants.json or regenerate it if it was gitignored and lost on a clean clone."],"exampleFix":"// before (constants.json)\n{ \"opencodeVersion\": \"\" }\n// after\n{ \"opencodeVersion\": \"1.0.4\" }","handlingStrategy":"validation","validationCode":"import { readFileSync } from \"node:fs\";\nconst constantsPath = path.resolve(desktopRoot, \"../../constants.json\");\nconst payload = JSON.parse(readFileSync(constantsPath, \"utf8\"));\nconst version = typeof payload?.opencodeVersion === \"string\" && payload.opencodeVersion.trim() ? payload.opencodeVersion.trim().replace(/^v/, \"\") : null;\nif (!version) throw new Error(`opencodeVersion missing or empty in ${constantsPath}`);","typeGuard":"function hasOpencodeVersion(p) {\n  return typeof p === \"object\" && p !== null && typeof p.opencodeVersion === \"string\" && p.opencodeVersion.trim().length > 0;\n}","tryCatchPattern":"try {\n  const cmd = await pinnedOpencodeInstallCommand();\n} catch (err) {\n  if (err.message.includes(\"missing opencodeVersion\")) {\n    logError(\"constants.json is malformed; regenerating from template\");\n  } else { throw err; }\n}","preventionTips":["Validate constants.json against a Zod schema at boot (opencodeVersion: z.string().min(1)).","Add a CI check that constants.json contains a non-empty opencodeVersion before packaging.","Never hand-edit constants.json — regenerate it via the pinned update script.","Keep the key camelCase exactly as the reader expects; guard against merge conflicts dropping it."],"tags":["config","json","versioning"],"backgroundTag":"missing-config-key","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}