{"record":{"id":"6e23e8654bf344d7","repo":"Yeachan-Heo/oh-my-codex","slug":"filepath-frontmatter-key-must-be-a-single","errorCode":null,"errorMessage":"${filePath} frontmatter \"${key}\" must be a single-line string","messagePattern":"(.+?) frontmatter \"(.+?)\" must be a single-line string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/setup.ts","lineNumber":2218,"sourceCode":"\treturn srcContent !== dstContent;\n}\n\nfunction containsTomlKey(content: string, key: string): boolean {\n\tconst escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\treturn new RegExp(`^\\\\s*${escapedKey}\\\\s*=`, \"m\").test(content);\n}\n\nfunction parseSkillFrontmatterScalar(\n\tvalue: string,\n\tkey: string,\n\tfilePath: string,\n): string {\n\tconst trimmed = value.trim();\n\tif (!trimmed) {\n\t\tthrow new Error(`${filePath} frontmatter \"${key}\" must not be empty`);\n\t}\n\tif (trimmed === \"|\" || trimmed === \">\") {\n\t\tthrow new Error(\n\t\t\t`${filePath} frontmatter \"${key}\" must be a single-line string`,\n\t\t);\n\t}\n\n\tconst quote = trimmed[0];\n\tif (quote === '\"' || quote === \"'\") {\n\t\tif (trimmed.length < 2 || trimmed.at(-1) !== quote) {\n\t\t\tthrow new Error(\n\t\t\t\t`${filePath} frontmatter \"${key}\" has an unterminated quoted string`,\n\t\t\t);\n\t\t}\n\t\tconst unquoted = trimmed.slice(1, -1).trim();\n\t\tif (!unquoted) {\n\t\t\tthrow new Error(`${filePath} frontmatter \"${key}\" must not be empty`);\n\t\t}\n\t\treturn unquoted;\n\t}\n","sourceCodeStart":2200,"sourceCodeEnd":2236,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/setup.ts#L2200-L2236","documentation":"The frontmatter parser only supports single-line scalars; a value of exactly '|' or '>' (YAML block scalar indicators) is rejected because multi-line block scalars are not supported for name/description.","triggerScenarios":"A frontmatter line such as 'description: |' or 'description: >' intending a folded/literal multi-line block.","commonSituations":"Authors copying multi-line YAML from other tools (CLAUDE.md, README generators) into SKILL.md; long descriptions written as blocks.","solutions":["Rewrite the value as a single-line quoted string","If it must be long, keep it on one line with quotes: description: \"long text...\"","Trim descriptions to a concise one-liner per skill conventions"],"exampleFix":"# before\n---\nname: s\ndescription: |\n  Long multi-line\n  description\n---\n# after\n---\nname: s\ndescription: \"Long multi-line description condensed to one line\"\n---","handlingStrategy":"validation","validationCode":"const usesBlockScalar = /^[^:]+:\\s*[|>]\\s*$/m.test(frontmatterText);\nif (usesBlockScalar) throw new Error(\"block scalars not supported in SKILL.md frontmatter\");","typeGuard":null,"tryCatchPattern":"try { parseSkillFrontmatter(content); } catch (e) { if (e instanceof Error && e.message.includes(\"single-line string\")) { /* rewrite block scalar as one-line quoted value */ } else throw e; }","preventionTips":["Write name/description as single-line values","Do not paste multi-line YAML blocks from other tools","Flatten long descriptions onto one quoted line"],"tags":["yaml","frontmatter","skill","validation","block-scalar"],"backgroundTag":"config-validation-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}