{"record":{"id":"dc8092c698f11a8c","repo":"googleapis/mcp-toolbox","slug":"error-executing-markdown-template-w","errorCode":null,"errorMessage":"error executing markdown template: %w","messagePattern":"error executing markdown template: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/internal/skills/generator.go","lineNumber":114,"sourceCode":"\t\t\tParametersSchema: parametersSchema,\n\t\t})\n\t}\n\n\tdata := skillTemplateData{\n\t\tSkillName:        skillName,\n\t\tSkillDescription: skillDescription,\n\t\tAdditionalNotes:  additionalNotes,\n\t\tTools:            toolsData,\n\t}\n\n\ttmpl, err := template.New(\"markdown\").Parse(skillTemplate)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error parsing markdown template: %w\", err)\n\t}\n\n\tvar buf strings.Builder\n\tif err := tmpl.Execute(&buf, data); err != nil {\n\t\treturn \"\", fmt.Errorf(\"error executing markdown template: %w\", err)\n\t}\n\n\treturn buf.String(), nil\n}\n\nconst nodeScriptTemplate = `#!/usr/bin/env node\n{{if .LicenseHeader}}\n{{.LicenseHeader}}\n{{end}}\nconst { spawn, execSync } = require('child_process');\nconst path = require('path');\nconst fs = require('fs');\nconst os = require('os');\n\nconst toolName = \"{{.Name}}\";\nconst configArgs = [{{.ConfigArgs}}];\n{{if .OptionalVars}}\nconst OPTIONAL_VARS_TO_OMIT_IF_EMPTY = [","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/cmd/internal/skills/generator.go#L96-L132","documentation":"`generateSkillMarkdown` throws \"error executing markdown template: %w\" when the parsed template fails during `tmpl.Execute(&buf, data)` — i.e., the data injected into the template triggered an execution error (e.g., calling a method/field on a nil value, a pipeline returning an error, or a write failure to the strings.Builder). Parsing succeeded; rendering with the given `data` struct did not.","triggerScenarios":"`tmpl.Execute` is called with the skill data struct (name, description, additionalNotes, toolsData) and a field access or method invoked inside `skillTemplate` fails at runtime, or the writer returns an error.","commonSituations":"Nil map/pointer fields in the data struct dereferenced by template actions like `{{ range .Tools }}` or `{{ .SomeField.Method }}`; a template function changed signature after a refactor; out-of-memory/write errors are rare but possible.","solutions":["Read the wrapped execution error — text/template reports the failing template node and line","Check that all fields referenced in `skillTemplate` exist on the data struct and are non-nil where used","Guard template actions with `{{ if ... }}` before ranging/dereferencing possibly-empty values","Re-run `TestGenerateSkillMarkdown` with the failing data to reproduce locally"],"exampleFix":"// before (template): {{ range .Tools }}...{{ end }} panics/execs nil\n// after (template): {{ if .Tools }}{{ range .Tools }}...{{ end }}{{ end }}","handlingStrategy":"try-catch","validationCode":"// Ensure data fields the template ranges over are non-nil before executing\nif data.Tools == nil { data.Tools = []toolsData{} }\nif err := validateTemplateFields(data); err != nil { return \"\", err }","typeGuard":null,"tryCatchPattern":"var buf strings.Builder\nif err := tmpl.Execute(&buf, data); err != nil {\n\treturn \"\", fmt.Errorf(\"error executing markdown template: %w\", err)\n}","preventionTips":["Guard template actions with `{{ if }}` before ranging/dereferencing optional fields","Keep the template's field references in sync with the data struct; rename together","Cover generateSkillMarkdown with table tests including empty/nil tool data","Check the wrapped error's template line when execution fails"],"tags":["go","template","text-template","codegen"],"backgroundTag":"template-execution-error","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}