zeroclaw-labs/zeroclaw · error

LINKEDIN_ACCESS_TOKEN not found in .env for update

Error message

LINKEDIN_ACCESS_TOKEN not found in .env for update

What it means

update_env_token rewrites the workspace .env in place, replacing the value on the existing LINKEDIN_ACCESS_TOKEN line while preserving comments, quoting style, and neighboring keys. It refuses to invent the key: if no line defines LINKEDIN_ACCESS_TOKEN it bails, so a token refresh never silently strands the new token outside the file.

Source

Thrown at crates/zeroclaw-tools/src/linkedin_client.rs:800

                } else {
                    new_token.to_string()
                };

                let new_line = if has_export {
                    format!("export LINKEDIN_ACCESS_TOKEN={}", new_val)
                } else {
                    format!("LINKEDIN_ACCESS_TOKEN={}", new_val)
                };

                updated_lines.push(new_line);
                found = true;
            } else {
                updated_lines.push(line.to_string());
            }
        }

        if !found {
            anyhow::bail!("LINKEDIN_ACCESS_TOKEN not found in .env for update");
        }

        // Preserve trailing newline if original had one
        let mut output = updated_lines.join("\n");
        if content.ends_with('\n') {
            output.push('\n');
        }

        tokio::fs::write(&env_path, &output)
            .await
            .with_context(|| format!("Failed to write {}", env_path.display()))?;

        Ok(())
    }
}

// ── Image Generation ─────────────────────────────────────────────

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Add a LINKEDIN_ACCESS_TOKEN=... line to the workspace .env, then retry the refresh
  2. If the value lives only in the process environment, write it into .env once so future updates have a line to rewrite
  3. Confirm the workspace_dir passed to LinkedInClient is the directory that actually contains the .env being edited

Example fix

# before (.env has no token line)
LINKEDIN_CLIENT_ID=...
LINKEDIN_CLIENT_SECRET=...

# after
LINKEDIN_CLIENT_ID=...
LINKEDIN_CLIENT_SECRET=...
LINKEDIN_ACCESS_TOKEN=placeholder-will-be-rewritten-on-refresh
Defensive patterns

Strategy: validation

Validate before calling

fn env_has_key(dir: &Path, key: &str) -> bool {
    std::fs::read_to_string(dir.join(".env"))
        .map(|c| c.lines().any(|l| {
            let l = l.trim();
            l.starts_with(&format!("{key}=")) || l.starts_with(&format!("export {key}="))
        }))
        .unwrap_or(false)
}

if !env_has_key(&workspace_dir, "LINKEDIN_ACCESS_TOKEN") {
    anyhow::bail!("refusing to refresh: no LINKEDIN_ACCESS_TOKEN line in .env");
}

Try / catch

Catch and treat as a setup defect: stop the refresh flow, write the placeholder line into .env, and rerun — retrying unchanged will keep failing.

Prevention

When it happens

Trigger: Calling update_env_token when .env never contained the key (the process env var was used instead); the line was deleted or commented out; .env was regenerated from a template without the key; the client was built with a workspace_dir that does not contain the real .env.

Common situations: Fresh clones missing the .env template line; CI systems that inject environment variables instead of a file; scripts that rebuild .env from scratch and drop the token line.

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 zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/5d20e6fa94614e00. Report an issue: GitHub.