{"record":{"id":"ea14f0f19de21983","repo":"can1357/oh-my-pi","slug":"expected-value-after","errorCode":null,"errorMessage":"Expected value after ':'","messagePattern":"Expected value after ':'","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/json-parse.ts","lineNumber":283,"sourceCode":"\t\t\t}\n\t\t\tif (c === \",\") {\n\t\t\t\t// Tolerate leading / doubled / trailing commas.\n\t\t\t\tthis.#i++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst key = this.#key();\n\t\t\tthis.#ws();\n\t\t\tif (this.#i < this.#n && this.#s[this.#i] === \":\") {\n\t\t\t\tthis.#i++;\n\t\t\t} else if (this.#partial) {\n\t\t\t\treturn out;\n\t\t\t} else {\n\t\t\t\tthrow new SyntaxError(\"Expected ':' in object\");\n\t\t\t}\n\t\t\tthis.#ws();\n\t\t\tif (this.#i >= this.#n) {\n\t\t\t\tif (this.#partial) return out;\n\t\t\t\tthrow new SyntaxError(\"Expected value after ':'\");\n\t\t\t}\n\t\t\tconst value = this.#value(true);\n\t\t\tif (value === INCOMPLETE) return out;\n\t\t\tout[key] = value;\n\t\t\tthis.#ws();\n\t\t\tconst d = this.#i < this.#n ? this.#s[this.#i] : \"\";\n\t\t\tif (d === \",\") {\n\t\t\t\tthis.#i++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (d === \"}\") {\n\t\t\t\tthis.#i++;\n\t\t\t\treturn out;\n\t\t\t}\n\t\t\tif (this.#partial) return out;\n\t\t\tthrow new SyntaxError(\"Expected ',' or '}' in object\");\n\t\t}\n\t}","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/json-parse.ts#L265-L301","documentation":"Thrown by RelaxedJson.#object in strict mode when a ':' was consumed but end-of-input is reached before any value follows. The key/value pair cannot be completed, so strict mode refuses the input; partial mode would return the object parsed so far.","triggerScenarios":"parseJsonWithRepair with input ending right after a colon: '{\"a\":' or '{\"a\": '. Occurs whenever a truncated payload happens to cut exactly between the colon and the value.","commonSituations":"LLM tool-call argument stream truncated mid-pair; a fixed-size read that cut the payload; log capture that clipped the buffer.","solutions":["Ensure the full payload is read before parsing (await the stream/file completion)","Use parseStreamingJson for genuinely incomplete input — it auto-closes and returns the partial object","Use classifyJsonPrefix to know the buffer is still a 'prefix' and wait for more deltas before final parsing"],"exampleFix":"// before\nconst v = parseJsonWithRepair(`{\"a\":`); // SyntaxError: Expected value after ':'\n// after\nconst v = parseStreamingJson(`{\"a\":`); // {} (partial-safe)","handlingStrategy":"validation","validationCode":"import { classifyJsonPrefix } from \"@oh-my-pi/pi-utils/json-parse\";\nif (classifyJsonPrefix(text) !== \"complete\") {\n  // input still incomplete (e.g. ends after ':') — do not final-parse yet\n}","typeGuard":null,"tryCatchPattern":"try {\n  const value = parseJsonWithRepair<T>(text);\n} catch (err) {\n  if (err instanceof SyntaxError && err.message === \"Expected value after ':'\") {\n    const partial = parseStreamingJson<T>(text); // returns object parsed so far\n  } else throw err;\n}","preventionTips":["Wait for stream completion before final-parsing","Use parseStreamingJson/parseStreamingJsonThrottled for streaming tool-call buffers","Check content-length / stream end events before treating a buffer as final"],"tags":["json","parse","truncated","object"],"backgroundTag":"json-unterminated-object","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}