zeroclaw-labs/zeroclaw · error · syn::Error

unknown credential_class `{class}`; expected encrypted_secre

Error message

unknown credential_class `{class}`; expected encrypted_secret, path_only_reference, public_value, external_auth_store, legacy_env_path, or requires_follow_up

What it means

The Configurable derive macro accepts a credential_class attribute whose value must be one of a closed vocabulary that maps to credential-handling variants (encrypted_secret, path_only_reference, public_value, external_auth_store, legacy_env_path, requires_follow_up). extract_credential_class emits a syn::Error at the attribute's span for any other string, so the build fails at compile time with the allowed list printed.

Source

Thrown at crates/zeroclaw-macros/src/lib.rs:2667

        return Some(lit_str.value());
    }
    None
}

fn extract_credential_class(attrs: &[syn::Attribute]) -> syn::Result<proc_macro2::TokenStream> {
    let Some(class) = extract_string_attr(attrs, "credential_class") else {
        return Ok(quote! { None });
    };

    let variant = match class.as_str() {
        "encrypted_secret" => quote! { EncryptedSecret },
        "path_only_reference" => quote! { PathOnlyReference },
        "public_value" => quote! { PublicValue },
        "external_auth_store" => quote! { ExternalAuthStore },
        "legacy_env_path" => quote! { LegacyEnvPath },
        "requires_follow_up" => quote! { RequiresFollowUp },
        _ => {
            return Err(syn::Error::new(
                proc_macro2::Span::call_site(),
                format!(
                    "unknown credential_class `{class}`; expected encrypted_secret, \
                     path_only_reference, public_value, external_auth_store, \
                     legacy_env_path, or requires_follow_up"
                ),
            ));
        }
    };

    Ok(quote! {
        Some(crate::config::CredentialSurfaceClass::#variant)
    })
}

/// Shared `set_prop` delegation gate for nested sites whose dotted namespace
/// is (or may be) shared with sibling candidates: serde-flatten fields,
/// `Option<T>` nested fields, and the two-level dotted-key candidate loop.

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Change the value to exactly one of the six listed classes, matching how the field's secret is actually stored.
  2. Pick encrypted_secret for values the runtime encrypts at rest, path_only_reference for fields that only name a file path, public_value for non-secret data, external_auth_store, legacy_env_path, or requires_follow_up accordingly.
  3. If you expected a newer class name, upgrade zeroclaw-macros to the version whose derive supports it.
  4. Check the derive macro's README/tests for the canonical usage example of the class you want.

Example fix

// before
#[derive(Configurable)]
#[credential_class = "secret"]
pub struct ApiConfig { pub api_key: String }

// after
#[derive(Configurable)]
#[credential_class = "encrypted_secret"]
pub struct ApiConfig { pub api_key: String }
Defensive patterns

Strategy: validation

Type guard

const VALID_CREDENTIAL_CLASSES: &[&str] = &["encrypted_secret","path_only_reference","public_value","external_auth_store","legacy_env_path","requires_follow_up"];

fn credential_class_valid(v: &str) -> bool {
    VALID_CREDENTIAL_CLASSES.contains(&v)
}

Prevention

When it happens

Trigger: Writing #[configurable(credential_class = "secret")] (or any non-listed value) on a struct deriving Configurable; the proc macro parses the literal, falls through the match, and returns the compile error.

Common situations: Typos in the attribute literal, docs written for a newer zeroclaw-macros with an added class compiled against an older crate, copy-pasting attribute blocks between projects, guessing the value instead of checking the list.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/4f0596cceccc38e6. Report an issue: GitHub.