hcengineering/platform · error · Error

Variable ${matched[0]} not found

Error message

Variable ${matched[0]} not found

What it means

The Huly YAML header parser supports variable interpolation: any ${VAR} token found in a string header value is replaced with a value from the parser's `variables` map. If the token is not present in that map, resolveValue throws 'Variable ${VAR} not found'. This keeps undefined placeholders from silently leaking into imported data.

Source

Thrown at packages/importer/src/huly/parser.ts:69

      ;(data as any)[key] = this.resolveValue(value)
    }
    return data
  }

  private resolveValue (value: any): any {
    if (typeof value === 'object') {
      if (Array.isArray(value)) {
        return value.map((v) => this.resolveValue(v))
      } else {
        return this.resolveProps(value)
      }
    } else if (typeof value === 'string') {
      while (true) {
        const matched = VARIABLE_REGEX.exec(value)
        if (matched === null) break
        const result = this.variables[matched[0]]
        if (result === undefined) {
          throw new Error(`Variable ${matched[0]} not found`)
        } else {
          value = value.replaceAll(matched[0], result)
          VARIABLE_REGEX.lastIndex = 0
        }
      }
      return value
    }
    return value
  }
}

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Add the missing key to the parser's variables map (or pass it where the HulyFormatImporter constructs the parser) so the token resolves.
  2. Correct or remove the ${...} placeholder in the file's YAML header if it is a typo or not needed.
  3. If the ${...} text is literal content, move it out of the YAML header into the markdown body, or escape/rewrite it so VARIABLE_REGEX does not match.

Example fix

// before (header uses undefined variable)
title: Guide for ${product}
// after (variable supplied to parser)
new HulyParser(variables: { '${product}': 'Huly' })
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-scan header strings for unresolved variables
const used = [...JSON.stringify(header).matchAll(/\$\{[^}]+\}/g)].map((m) => m[0])
const missing = used.filter((v) => !(v in variables))
if (missing.length > 0) throw new Error(`Unresolved variables: ${missing.join(', ')}`)

Try / catch

try {
  const header = parser.readYamlHeader(filePath)
} catch (e) {
  if ((e as Error).message.includes('not found') && /Variable \$\{/.test((e as Error).message)) {
    const name = (e as Error).message.match(/Variable (\$\{[^}]+\})/)?.[1]
    console.error(`Define '${name}' in parser variables or remove it from ${filePath}`)
  } else throw e
}

Prevention

When it happens

Trigger: A YAML header in a parsed markdown file contains a ${...} placeholder (matching VARIABLE_REGEX) whose exact token (e.g. '${workspace}') is not a key in the variables passed to the parser; this runs during readYamlHeader -> resolveProps -> resolveValue, recursively for nested objects and arrays.

Common situations: Header references a variable the importer never defines; markdown content legitimately containing shell-style ${...} (e.g. code samples) placed in the YAML header; typo in variable name; variable defined with different casing or missing $ braces.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/ff8ed4470d9631dd. Report an issue: GitHub.