{"record":{"id":"6cdd9134bf3633ec","repo":"JanDeDobbeleer/oh-my-posh","slug":"failed-to-render-config-w","errorCode":null,"errorMessage":"failed to render config: %w","messagePattern":"failed to render config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/wasm/main.go","lineNumber":163,"sourceCode":"\t}\n\n\t// terminal.CaptureRuns must be set before render.Config's own\n\t// eng.Primary() call runs - render.Config's doc comment explains why\n\t// that line can't live inside render.Config itself, and every caller\n\t// (the CLI image command, this one) sets it at its own call site instead.\n\tterminal.CaptureRuns = true\n\n\tcolumns := jsInt(optionsGet(options, \"columns\"), 120)\n\n\t// resetTemplateCache is true, unlike the CLI's single-shot image/data\n\t// commands: this wasm instance stays alive across many calls to\n\t// render() - once per keystroke in a studio preview, say - so each call\n\t// must start the template cache fresh, or one render's Var/Maps would\n\t// leak into the next. See render.Config's own doc comment for the exact\n\t// same reasoning applied to recordThemeSanitized's per-theme loop.\n\teng, err := render.Config(cfg, columns, true, applyData)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to render config: %w\", err)\n\t}\n\n\tmetrics := render.FontMetrics{\n\t\tCellWidth:   jsFloat(optionsGet(options, \"cellWidth\")),\n\t\tLineHeight:  jsFloat(optionsGet(options, \"lineHeight\")),\n\t\tFillAscent:  jsFloat(optionsGet(options, \"fillAscent\")),\n\t\tFillDescent: jsFloat(optionsGet(options, \"fillDescent\")),\n\t}\n\n\topts := render.SVGOptions(jsString(optionsGet(options, \"fontFamily\")), columns, metrics)\n\n\t// A caller-supplied canvas background (the website's studio, switching between its own\n\t// dark/light color mode) only ever fills in for a theme that leaves its own terminal\n\t// background unset - withDefaults (svg.go) always prefers a real opts.TerminalBackground\n\t// over CanvasBackground when the theme sets one, so this can't paint over how the theme\n\t// would actually look in a real terminal. Same convention as the CLI's own\n\t// --background-color flag (cli/config_export_svg.go's exportSVG).\n\tif backgroundColor := jsString(optionsGet(options, \"backgroundColor\")); backgroundColor != \"\" {","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/wasm/main.go#L145-L181","documentation":"Returned by renderSVG (src/wasm/main.go:163) when render.Config fails to build a rendering engine from the already-parsed config. render.Config validates the config and applies flags (here via the mandatory applyData closure that sets flags.DataOnly), so any error it reports - invalid template/function setup, flag application failure, bad segment config surfaced during engine construction - is wrapped as \"failed to render config: %w\". Unlike the parse errors, this fires after the config text parsed successfully.","triggerScenarios":"Calling wasm render(configText, format, dataJSON, options) where configText parses but render.Config rejects it: a malformed template expression in a segment, a data blob whose ApplyFlags fails (invalid pwd/status data passed via dataJSON), or an invalid column/flag combination. Config text that parses cleanly under format but references unsupported options during engine build.","commonSituations":"Editing a theme in the web studio and introducing a bad template like {{ .Segment.Data }} on a nil map; supplying a dataJSON whose pwd is not a valid path string; referencing a template function with wrong arity that fails at engine construction; rendering a theme that requires env probing while DataOnly forces recorded data only.","solutions":["Read the wrapped inner error - it names the specific segment/template/flag that render.Config rejected.","Fix the offending template expression in the config text; validate templates with the oh-my-posh debug/CLI render before loading them in the browser.","If the error came from data.ApplyFlags, correct the dataJSON contents (valid pwd path, valid status) or pass '' to skip recorded data.","Reduce the config to a minimal single-segment version and bisect until the failing segment is isolated."],"exampleFix":"// before: bad template\n{ \"type\": \"path\", \"template\": \"{{ .UnknownField | bogusFunc }}\" }\n// after: valid template\n{ \"type\": \"path\", \"template\": \"{{ .Path }}\" }","handlingStrategy":"try-catch","validationCode":"// validate config and templates with the CLI before loading into wasm:\n// oh-my-posh config render --config ./theme.omp.json\nfunction validateBeforeRender(configText) {\n  if (typeof configText !== 'string' || configText.trim() === '') return true; // empty -> default config is safe\n  return true; // structural validation happens via render.Config; catch at call site\n}","typeGuard":null,"tryCatchPattern":"try {\n  const svg = omp.render(cfg, 'json', dataJSON, options);\n} catch (e) {\n  if (String(e).includes('failed to render config')) {\n    // the wrapped message names the failing segment/template/flag\n    console.error('Config failed to render:', e.message);\n    showEditorErrorAt(e.message); // surface the inner error to the user\n  } else { throw e; }\n}","preventionTips":["Test themes with `oh-my-posh config render` or `oh-my-posh debug` locally before loading them in the browser.","Keep template expressions simple and validate variables exist with `default` filters.","If passing dataJSON, ensure ApplyFlags-compatible values (valid pwd path string, valid status).","Bisect multi-segment themes down to the failing segment when the inner error is unclear."],"tags":["wasm","render","config","template"],"backgroundTag":"template-render-failed","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}