Add format string validation (#292)

Validates format() function calls for:
- Invalid syntax (missing closing brace, empty placeholder, non-numeric placeholder)
- Argument count mismatch (placeholder references arg that doesn't exist)

Port of Go's format_validator.go from actions-workflow-parser.
This commit is contained in:
eric sciple
2026-01-08 09:25:37 -06:00
committed by GitHub
parent dbf7752734
commit 54404aa9ff
3 changed files with 495 additions and 0 deletions
+23
View File
@@ -27,6 +27,7 @@ import {mapRange} from "./utils/range.js";
import {getOrConvertWorkflowTemplate, getOrParseWorkflow} from "./utils/workflow-cache.js";
import {validateActionReference} from "./validate-action-reference.js";
import {validateAction} from "./validate-action.js";
import {validateFormatCalls} from "./validate-format-string.js";
import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config.js";
import {defaultValueProviders} from "./value-providers/default.js";
@@ -735,6 +736,28 @@ async function validateExpression(
continue;
}
// Validate format() function calls
const formatErrors = validateFormatCalls(expr);
for (const formatError of formatErrors) {
if (formatError.type === "invalid-syntax") {
diagnostics.push({
message: `Invalid format string: ${formatError.message}`,
range: mapRange(expression.range),
severity: DiagnosticSeverity.Error,
code: "invalid-format-string"
});
} else if (formatError.type === "arg-count-mismatch") {
diagnostics.push({
message: `Format string references argument {${formatError.expected - 1}} but only ${
formatError.provided
} argument(s) provided`,
range: mapRange(expression.range),
severity: DiagnosticSeverity.Error,
code: "format-arg-count-mismatch"
});
}
}
const context = await getWorkflowExpressionContext(
namedContexts,
contextProviderConfig,