argoproj/argo-workflows · error
unable to parse node field selector '%s': %w
Error message
unable to parse node field selector '%s': %w
What it means
Thrown by `argo archive retry` (retryArchivedWorkflows in cmd/argo/commands/archive/retry.go) when the --node-field-selector flag cannot be parsed as a Kubernetes field selector (fields.ParseSelector fails). Argo uses this selector to pick which failed nodes of the archived workflow to retry.
Source
Thrown at cmd/argo/commands/archive/retry.go:127
command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage())
command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is retried")
command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is retried")
command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes")
command.Flags().BoolVar(&retryOpts.restartSuccessful, "restart-successful", false, "indicates to restart successful nodes matching the --node-field-selector")
command.Flags().StringVar(&retryOpts.nodeFieldSelector, "node-field-selector", "", "selector of nodes to reset, eg: --node-field-selector inputs.parameters.myparam.value=abc")
command.Flags().StringVarP(&retryOpts.labelSelector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
command.Flags().StringVar(&retryOpts.fieldSelector, "field-selector", "", "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.")
command.Flags().BoolVar(&retryOpts.forceName, "name", false, "force the argument to be treated as a name")
command.Flags().BoolVar(&retryOpts.forceUID, "uid", false, "force the argument to be treated as a UID")
command.MarkFlagsMutuallyExclusive("name", "uid")
return command
}
// retryArchivedWorkflows retries workflows by given retryArgs or workflow names/UIDs
func retryArchivedWorkflows(ctx context.Context, archiveServiceClient workflowarchivepkg.ArchivedWorkflowServiceClient, serviceClient workflowpkg.WorkflowServiceClient, retryOpts retryOps, cliSubmitOpts common.CliSubmitOpts, args []string) error {
selector, err := fields.ParseSelector(retryOpts.nodeFieldSelector)
if err != nil {
return fmt.Errorf("unable to parse node field selector '%s': %w", retryOpts.nodeFieldSelector, err)
}
var wfs wfv1.Workflows
if retryOpts.hasSelector() {
wfs, err = listArchivedWorkflows(ctx, archiveServiceClient, retryOpts.fieldSelector, retryOpts.labelSelector, 0)
if err != nil {
return err
}
}
// Add workflows from args - auto-detect UID vs NAME
for _, identifier := range args {
var uid string
uid, err = resolveUID(ctx, archiveServiceClient, identifier, retryOpts.namespace, retryOpts.forceUID, retryOpts.forceName)
if err != nil {
return fmt.Errorf("resolve UID: %w", err)
}
wf := wfv1.Workflow{
ObjectMeta: metav1.ObjectMeta{View on GitHub (pinned to 35bff19146)
Solutions
- Fix the selector syntax: valid form is key=value pairs, e.g. `--node-field-selector 'metadata.name=step-name'`.
- Verify quoting: wrap the selector in single quotes so the shell does not split on '=' or spaces.
- Only use keys supported by node field selectors (metadata.name, metadata.namespace, status.phase, etc.) — arbitrary template field keys are invalid.
- Omit --node-field-selector to retry all failed nodes, then narrow once the retry works.
Example fix
// before argo archive retry --node-field-selector 'inputs.parameters.x==foo' <wf> // after argo archive retry --node-field-selector 'metadata.name=my-step' <wf>
Defensive patterns
Strategy: validation
Validate before calling
import "k8s.io/apimachinery/pkg/fields"
sel, err := fields.ParseSelector(nodeFieldSelector)
if err != nil {
return fmt.Errorf("invalid --node-field-selector %q: %w", nodeFieldSelector, err)
}
// only allow supported keys
for _, r := range sel.Requirements() {
switch r.Key {
case "metadata.name", "metadata.namespace", "status.phase":
default:
return fmt.Errorf("unsupported node field selector key %q", r.Key)
}
} Try / catch
if err := retryArchivedWorkflows(...); err != nil {
if strings.Contains(err.Error(), "unable to parse node field selector") {
// correct the selector syntax (key=value) before retrying
}
return err
} Prevention
- Use key=value syntax (single =, no ==) in node field selectors.
- Quote selectors in shells to protect = and spaces.
- Restrict to supported keys: metadata.name, metadata.namespace, status.phase.
- Test the selector against `argo get <wf>` output node names first.
When it happens
Trigger: Running `argo archive retry --node-field-selector 'invalid selector ==='` (or similar malformed syntax) with any identifier/selector; fields.ParseSelector rejects the string before any server call.
Common situations: Hand-written selector syntax with wrong operators (e.g. '==' vs '=', unsupported keys like status instead of the required metadata.name / status.phase style keys used by the retry API); quoting issues in shells stripping or mangling the selector; copying node-field-selector values intended for `kubectl get` with different field semantics.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse node field selector '%s': %w
- unable to parse node field selector '%s': %w
- unable to parse node field selector '%s': %w
- unable to parse node field selector '%s': %w
- ${e.Usage()}
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/e2e866e2fb37810b.
Report an issue: GitHub.