Troubleshooting: Integrations
Google Workspace
OAuth token expired or revoked
Google OAuth refresh tokens can be revoked (by the user, by Google, or by inactivity). When this happens:
Google OAuth token exchange failedOr you will see 401 errors on Google API calls.
Fix: Re-authenticate:
bash
triggerfish connect googleThis opens a browser for the OAuth consent flow. After granting access, the new tokens are stored in the keychain.
"No refresh token"
The OAuth flow returned an access token but no refresh token. This happens when:
- You have already authorised the app before (Google only sends the refresh token on the first authorisation)
- The OAuth consent screen did not request offline access
Fix: Revoke the app's access in Google Account Settings, then run triggerfish connect google again. This time Google will send a fresh refresh token.
Concurrent refresh prevention
If multiple requests trigger a token refresh at the same time, Triggerfish serialises them so only one refresh request is sent. If you see timeouts during token refresh, it may be that the first refresh is taking too long.
GitHub
"GitHub token not found in keychain"
The GitHub integration stores the Personal Access Token in the OS keychain under the key github-pat.
Fix:
bash
triggerfish connect github
# or manually:
triggerfish config set-secret github-pat ghp_...Token format
GitHub supports two token formats:
- Classic PATs:
ghp_... - Fine-grained PATs:
github_pat_...
Both work. The setup wizard verifies the token by calling the GitHub API. If verification fails:
GitHub token verification failed
GitHub API request failedDouble-check the token has the required scopes. For full functionality, you need: repo, read:org, read:user.
Clone failures
The GitHub clone tool has auto-retry logic:
- First attempt: clones with the specified
--branch - If the branch does not exist: retries without
--branch(uses default branch)
If both attempts fail:
Clone failed on retry
Clone failedCheck:
- Token has
reposcope - Repository exists and the token has access
- Network connectivity to github.com
Rate limiting
GitHub's API rate limit is 5,000 requests/hour for authenticated requests. The rate limit remaining count and reset time are extracted from response headers and included in error messages:
Rate limit: X remaining, resets at HH:MM:SSThere is no automatic backoff. Wait for the rate limit window to reset.
Notion
"Notion enabled but token not found in keychain"
The Notion integration requires an internal integration token stored in the keychain.
Fix:
bash
triggerfish connect notionThis prompts for the token and stores it in the keychain after verifying it with the Notion API.
Token format
Notion uses two token formats:
- Internal integration tokens:
ntn_... - Legacy tokens:
secret_...
Both are accepted. The connect wizard validates the format before storing.
Rate limiting (429)
Notion's API is rate-limited to approximately 3 requests per second. Triggerfish has built-in rate limiting (configurable) and retry logic:
- Default rate: 3 requests/second
- Retries: up to 3 times on 429
- Backoff: exponential with jitter, starting at 1 second
- Honours the
Retry-Afterheader from Notion's response
If you still hit rate limits:
Notion API rate limited, retryingReduce concurrent operations or lower the rate limit in config.
404 Not Found
Notion: 404 Not FoundThe resource exists but is not shared with your integration. In Notion:
- Open the page or database
- Click "..." menu > "Connections"
- Add your Triggerfish integration
"client_secret removed" (Breaking Change)
In a security update, the client_secret field was removed from the Notion config. If you have this field in your triggerfish.yaml, remove it. Notion now uses only the OAuth token stored in the keychain.
Network errors
Notion API network request failed
Notion API network error: <message>The API is unreachable. Check your network connection. If you are behind a corporate proxy, Notion's API (api.notion.com) must be accessible.
CalDAV (Calendar)
Credential resolution failed
CalDAV credential resolution failed: missing username
CalDAV credential resolution failed: secret not foundThe CalDAV integration needs a username and password:
yaml
caldav:
server_url: "https://calendar.example.com/dav"
username: "your-username"
credential_ref: "secret:caldav:password"Store the password:
bash
triggerfish config set-secret caldav:password <your-password>Discovery failures
CalDAV uses a multi-step discovery process:
- Find the principal URL (PROPFIND on well-known endpoint)
- Find the calendar-home-set
- List available calendars
If any step fails:
CalDAV principal discovery failed
CalDAV calendar-home-set discovery failed
CalDAV calendar listing failedCommon causes:
- Wrong server URL (some servers need
/dav/principals/or/remote.php/dav/) - Credentials rejected (wrong username/password)
- Server does not support CalDAV (some servers advertise WebDAV but not CalDAV)
ETag mismatch on update/delete
ETag mismatch — the event was modified by another client. Fetch the latest version and retry.CalDAV uses ETags for optimistic concurrency control. If another client (phone, web) modified the event between your read and your update, the ETag will not match.
Fix: The agent should fetch the event again to get the current ETag, then retry the operation. This is handled automatically in most cases.
"CalDAV credentials not available, executor deferred"
The CalDAV executor starts in a deferred state if credentials cannot be resolved at startup. This is non-fatal; the executor will report errors if you try to use CalDAV tools.
MCP (Model Context Protocol) Servers
Server not found
MCP server '<name>' not foundThe tool call references an MCP server that is not configured. Check your mcp_servers section in triggerfish.yaml.
Server binary not in PATH
MCP servers are spawned as subprocesses. If the binary is not found:
MCP server '<name>': <validation error>Common issues:
- The command (e.g.,
npx,python,node) is not in the daemon's PATH - systemd/launchd PATH issue: The daemon captures your PATH at install time. If you installed the MCP server tool after installing the daemon, re-install the daemon to update PATH:
bash
triggerfish stop
triggerfish dive --install-daemonServer crashes
If an MCP server process crashes, the read loop exits and the server becomes unavailable. There is no automatic reconnection.
Fix: Restart the daemon to re-spawn all MCP servers.
SSE transport blocked
MCP servers using SSE (Server-Sent Events) transport are subject to SSRF checks:
MCP SSE connection blocked by SSRF policySSE URLs pointing to private IP addresses are blocked. This is by design. Use the stdio transport for local MCP servers instead.
Tool call errors
tools/list failed: <message>
tools/call failed: <message>The MCP server responded with an error. This is the server's error, not Triggerfish's. Check the MCP server's own logs for details.
Obsidian
"Vault path does not exist"
Vault path does not exist: /path/to/vaultThe configured vault path in plugins.obsidian.vault_path does not exist. Make sure the path is correct and accessible.
Path traversal blocked
Path traversal rejected: <path>
Path escapes vault boundary: <path>A note path attempted to escape the vault directory (e.g., using ../). This is a security check. All note operations are confined to the vault directory.
Excluded folders
Path is excluded: <path>The note is in a folder listed in exclude_folders. To access it, remove the folder from the exclusion list.
Classification enforcement
Obsidian read blocked: classification exceeds session taint
Obsidian write-down blockedThe vault or specific folder has a classification level that conflicts with the session taint. See Security Troubleshooting for details on write-down rules.
