grafana/k6 · error
exec value cannot be empty
Error message
exec value cannot be empty
What it means
Emitted by BaseConfig.Validate (lib/executor/base_config.go:59-61) when the scenario's exec field is present and Valid but set to an empty string. exec is a null.String: it is only meant to hold the name of an exported JS function that this scenario should run instead of default. An explicitly empty string is treated as a configuration mistake — omitting the field entirely is the correct way to use the default function.
Source
Thrown at lib/executor/base_config.go:60
return BaseConfig{
Name: name,
Type: configType,
GracefulStop: types.NewNullDuration(DefaultGracefulStopValue, false),
}
}
// Validate checks some basic things like present name, type, and a positive start time
func (bc BaseConfig) Validate() (result []error) {
// Some just-in-case checks, since those things are likely checked in other places or
// even assigned by us:
if bc.Name == "" {
result = append(result, errors.New("scenario name can't be empty"))
}
if !scenarioNameWhitelist.MatchString(bc.Name) {
result = append(result, errors.New(scenarioNameErr))
}
if bc.Exec.Valid && bc.Exec.String == "" {
result = append(result, errors.New("exec value cannot be empty"))
}
if bc.Type == "" {
result = append(result, errors.New("missing or empty type field"))
}
// The actually reasonable checks:
if bc.StartTime.Duration < 0 {
result = append(result, errors.New("the startTime can't be negative"))
}
if bc.GracefulStop.Duration < 0 {
result = append(result, errors.New("the gracefulStop timeout can't be negative"))
}
return result
}
// GetName returns the name of the scenario.
func (bc BaseConfig) GetName() string {
return bc.Name
}View on GitHub (pinned to 93accf6570)
Solutions
- Remove the exec property from the scenario so it falls back to the default exported function
- Or set it to an actual exported function name defined in the script, e.g. exec: 'login'
- If the value comes from an env var, default it or conditionally include the property only when non-empty
Example fix
// before
export const options = {
scenarios: {
smoke: { executor: 'shared-iterations', exec: '' },
},
};
// after
export const options = {
scenarios: {
smoke: { executor: 'shared-iterations' }, // uses default export
},
}; Defensive patterns
Strategy: validation
Validate before calling
// Only include exec when it names a real exported function
const fn = __ENV.SCENARIO_FUNC;
export const options = {
scenarios: {
smoke: {
executor: 'shared-iterations',
...(fn ? { exec: fn } : {}),
},
},
}; Prevention
- Never write exec: '' — omit the key to use the default export
- When exec is env-driven, default it and assert the function exists: if (typeof globalThis[fn] !== 'function') throw new Error(...)
- Remember k6 only accepts exported top-level functions as exec targets
When it happens
Trigger: Setting scenarios: { smoke: { executor: 'per-vu-iterations', exec: '' } } in exported options, or unmarshaling scenario JSON that contains an "exec": "" member. Validate() fires during config validation before the test starts.
Common situations: Templated scripts that interpolate a function name from a variable which is empty (e.g. __ENV.SCENARIO_FUNC unset), or a leftover empty exec after commenting out the intended function name.
Related errors
- scenario name can't be empty
- the scenario name should contain only numbers, latin letters
- missing or empty type field
- the startTime can't be negative
- the gracefulStop timeout can't be negative
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/7b363a8a945596c1.
Report an issue: GitHub.