BoundaryML/baml · error

Failed to resolve {}

Error message

Failed to resolve {}

What it means

In the WASM (browser/JS) environment, GCP credentials that still contain an unresolved environment-variable placeholder (a string starting with '$') cannot be expanded, because the WASM runtime has no access to host environment variables. The auth strategy constructor bails with this message naming the unresolved string.

Source

Thrown at engine/baml-runtime/src/internal/llm_client/primitive/vertex/wasm_auth.rs:34

impl Token {
    pub fn as_str(&self) -> &str {
        &self.0
    }
}

impl VertexAuth {
    pub async fn get_or_create(auth_strategy: &ResolvedGcpAuthStrategy) -> Result<Arc<VertexAuth>> {
        // For WASM, just create new instances without caching
        let auth = Arc::new(Self::new(auth_strategy).await?);
        Ok(auth)
    }

    pub async fn new(auth_strategy: &ResolvedGcpAuthStrategy) -> Result<Self> {
        Ok(match auth_strategy {
            ResolvedGcpAuthStrategy::MaybeFilePath(str)
            | ResolvedGcpAuthStrategy::StringContainingJson(str) => {
                if str.starts_with("$") {
                    anyhow::bail!("Failed to resolve {}", str);
                }

                let debug_str = {
                    let s = serde_json::to_string(&serde_json::Value::String(str.clone()))
                        .expect("Serialization of string should always succeed");
                    if s.len() > 8 {
                        format!("{}...{}", &s[..4], &s[s.len() - 4..])
                    } else {
                        s
                    }
                };

                log::debug!("Attempting to auth using JsonString strategy");
                Self(Some(serde_json::from_str(str).context(format!("Failed to parse 'credentials' as GCP service account creds (are you using JSON format creds?); credentials={debug_str}"))?))
            }
            ResolvedGcpAuthStrategy::JsonObject(json) => {
                // NB: this should never happen in WASM, there's no way to pass a JSON object in
                log::debug!("Attempting to auth using JsonObject strategy");

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Inject the actual credential value (file path or JSON) into the runtime config instead of a $VAR reference when running in WASM
  2. Pre-resolve environment variables in your JS wrapper before passing config to the WASM runtime
  3. For browser deployments, use a proxy/backend to hold GCP credentials rather than embedding them client-side
  4. Verify the env var is set in the build/deploy pipeline so placeholder substitution actually occurs

Example fix

// before (WASM config with unresolved placeholder)
auth { strategy "StringContainingJson" "$GOOGLE_APPLICATION_CREDENTIALS_JSON" }
// after: resolve before passing in
const creds = process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON; // or injected at build time
auth { strategy "StringContainingJson" creds }
Defensive patterns

Strategy: validation

Validate before calling

function assertNoUnresolvedEnvVars(cfg) {
  for (const v of Object.values(cfg?.options?.credentials ?? {})) {
    if (typeof v === 'string' && v.startsWith('$')) {
      throw new Error(`Unresolved env placeholder '${v}' — resolve it before passing to the WASM runtime`);
    }
  }
}

Type guard

const isResolvedCredential = (v) => typeof v === 'string' && v.length > 0 && !v.startsWith('$');

Try / catch

try {
  const client = new BamlClient(config);
} catch (err) {
  if (String(err).startsWith('Failed to resolve $')) {
    throw new Error(`Env var ${String(err).split(' ')[3]} is unavailable in WASM; inject its value instead`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Running BAML compiled to WASM with a GCP auth strategy whose credentials path or JSON string is something like '$GOOGLE_APPLICATION_CREDENTIALS' and that env var was never substituted before reaching the runtime.

Common situations: Using the same BAML config on server (env vars resolved) and in the browser/WASM (env vars unavailable); forgetting to inline or inject the credential value in a web deployment.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/5cc8dd7ec9acddba. Report an issue: GitHub.