{"record":{"id":"ffb1018281e498de","repo":"microsoft/typescript-go","slug":"cannot-parse-string-enum-value-govalue","errorCode":null,"errorMessage":"Cannot parse string enum value: ${goValue}","messagePattern":"Cannot parse string enum value: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"Herebyfile.mjs","lineNumber":434,"sourceCode":"\r\n/**\r\n * Resolve a Go string-constant expression (e.g. `Prefix + \"call\"` or `\"export=\"`)\r\n * into a quoted, JS-escaped TypeScript string literal. `replacements` maps bare\r\n * Go identifiers (such as a sentinel-prefix constant) to their literal value.\r\n * @param {string} goValue\r\n * @param {Record<string, string>} replacements\r\n * @returns {string}\r\n */\r\nfunction parseGoStringValue(goValue, replacements) {\r\n    let result = \"\";\r\n    for (const part of goValue.split(\"+\").map(p => p.trim())) {\r\n        if (Object.prototype.hasOwnProperty.call(replacements, part)) {\r\n            result += replacements[part];\r\n            continue;\r\n        }\r\n        const stringMatch = part.match(/^\"((?:[^\"\\\\]|\\\\.)*)\"$/);\r\n        if (stringMatch === null) {\r\n            throw new Error(`Cannot parse string enum value: ${goValue}`);\r\n        }\r\n        // Interpret Go escape sequences via JSON, then re-stringify below.\r\n        result += JSON.parse(`\"${stringMatch[1]}\"`);\r\n    }\r\n    return JSON.stringify(result);\r\n}\r\n\r\n/**\r\n * @param {EnumDef} def\r\n * @returns {{ name: string, value: string }[]}\r\n */\r\nfunction parseGoEnum(def) {\r\n    const source = fs.readFileSync(def.goFile, \"utf-8\");\r\n    const constBlockRegex = /const\\s*\\(([\\s\\S]*?)\\n\\)/g;\r\n\r\n    for (const match of source.matchAll(constBlockRegex)) {\r\n        const members = parseGoConstBlock(match[1], def).filter(member => !def.excludeMembers?.includes(member.name));\r\n        if (members.length > 0) return topoSortMembers(members);\r","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/Herebyfile.mjs#L416-L452","documentation":"Tracing events are buffered in memory and flushed to <traceDir>/trace.json only when the buffer exceeds flushThreshold (256 KiB); maybeFlushLocked performs that AppendFile. Per the code's own contract, a flush failure is recorded in tr.flushErr and all subsequent writes become no-ops — the compiler keeps running and the error is only surfaced later from StopTracing. So seeing this error means trace output was silently truncated from the moment of the first failed flush onward.","triggerScenarios":"Any long tracing session that emits >256 KiB of events (large projects, heavy checkTypes phases) where AppendFile then fails: trace file deleted or truncated by an external process mid-session, permissions changed, disk full, or the FS handle invalidated (container/overlay teardown). The error originates at flush time but reaches the caller only when StopTracing returns it.","commonSituations":"Disk filling up during a full-project trace (trace files are large); a watcher/cleaner deleting the trace directory while tsgo runs; CI artifact collection moving files mid-run; tracing a monorepo where event volume crosses many flush thresholds.","solutions":["Free disk space or point traceDir at a volume with enough room, then re-run — the current session's trace is already incomplete.","Ensure nothing deletes/locks the trace file while the session is live (exclude traceDir from cleanup jobs and artifact-upload hooks).","Check permissions on traceDir and the trace file for the duration of the run (same user, writable).","Treat a StopTracing error as 'trace possibly truncated': re-run tracing after fixing I/O rather than trusting the partial file."],"exampleFix":"// before: error surfaces only at stop\nif err := tr.StopTracing(); err != nil { // \"failed to flush trace file: ...\"\n\tlog.Printf(\"trace incomplete: %v\", err)\n}\n\n// after: pre-flight writability check before a long session\nprobe := filepath.Join(traceDir, \".probe\")\nif err := os.WriteFile(probe, nil, 0o644); err != nil {\n\treturn fmt.Errorf(\"trace dir not writable: %w\", err)\n}\nos.Remove(probe)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// flush failures are deferred; only StopTracing reveals them\nif err := tr.StopTracing(); err != nil {\n\tif strings.Contains(err.Error(), \"failed to flush trace file\") {\n\t\t// trace is truncated from the first failed flush — discard and re-run\n\t\tlog.Printf(\"trace truncated: %v; re-run after freeing disk\", err)\n\t} else {\n\t\treturn err\n\t}\n}","preventionTips":["Ensure ample free disk before tracing (trace files grow with project size and event volume).","Keep the trace directory untouched for the whole process lifetime.","Don't ignore StopTracing's error — it is the only place flush failures surface.","Remember the design: after the first flush failure, later writes are no-ops, so the file is incomplete, never partially recoverable."],"tags":["tracing","io","disk-full","deferred-error"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}