# Troubleshooting Use this page to map symptoms to status checks and recovery actions. ## Function Does Not Exist for a Registration Call Symptom: ```text ERROR: function graph.add_table(unknown, unknown) does not exist HINT: No function matches the given name and argument types. ``` PostgreSQL treats a quoted table name as an `unknown` string unless you cast it to the `regclass` table-identifier type required by pgGraph registration APIs. This does not mean the extension or function is missing. Incorrect: ```sql SELECT graph.add_table('public.users', 'id'); ``` Fix: ```sql SELECT graph.add_table('public.users'::regclass, 'id'); ``` Use `::regclass` for table arguments to `graph.add_table()`, `graph.add_edge()`, traversal, path, search, and related APIs. PostgreSQL also validates that the named relation exists when it resolves the cast. ## Graph Not Built Symptom: ```text SQLSTATE 55000 DETAIL: pgGraph diagnostic: PG003 Graph not built. Call graph.build() first. ``` Check: ```sql SELECT node_count, edge_count, schema_status, invalid_reason FROM graph.status(); ``` Fix: ```sql SELECT * FROM graph.build(); ``` ## Node Not Found Symptom: ```text SQLSTATE P0002 DETAIL: pgGraph diagnostic: PG010 Node not found ``` Check: ```sql SELECT * FROM graph.search('id', 'expected_id', table_filter := 'public.my_table'::regclass, mode := 'exact'); SELECT * FROM graph.registered_tables(); ``` Likely causes: | Cause | Fix | |---|---| | Wrong table or ID string | Use exact source primary-key text | | Composite ID mismatch | Use JSON array text encoding from `graph.node_ref_string()` patterns | | Source row added after build | `graph.apply_sync()` or `graph.build()` | | Source row deleted/tombstoned | Rebuild or query another active node | ## Search Returns No Rows Check that the column is registered in `graph.add_table(..., columns := ...)`: ```sql SELECT * FROM graph.registered_tables() WHERE table_name = 'public.users'; ``` Then test exact mode and table filter: ```sql SELECT * FROM graph.search( 'name', 'Alice', table_filter := 'public.users'::regclass, mode := 'exact', hydrate := true ); ``` Search uses source-table SQL, so source table indexes matter. Add normal PostgreSQL indexes for high-volume searched columns. ## Traversal Returns Too Few Rows Check: ```sql SELECT * FROM graph.status(); SELECT * FROM graph.traverse( 'public.users'::regclass, 'u1', max_depth := 1, edge_types := NULL, direction := 'any', hydrate := false, max_nodes := 100000, max_frontier := 100000 ); ``` Likely causes: | Cause | Fix | |---|---| | `max_depth` too low | Increase `max_depth` | | `edge_types` filter excludes edges | Remove filter or inspect `edge_types` in `graph.status()` | | `direction` wrong for unidirectional edges | Use `out`, `in`, or register bidirectional edges | | `max_nodes` or `max_frontier` trips | Raise circuit breakers for trusted query | | Tenant scope excludes nodes | Pass correct `tenant` or session tenant | | Filter column not registered/rebuilt | Register filter column and rebuild | ## Unsupported Operation With Pending Overlays Symptom: ```text SQLSTATE 0A000 DETAIL: pgGraph diagnostic: PG018 Unsupported graph operation ``` Likely cause: | Cause | Fix | |---|---| | `graph.weighted_shortest_path()` ran while `edge_buffer_used > 0` | Run `graph.vacuum()` or `graph.maintenance()` to merge pending edge overlays, then retry | Unweighted traversal, unweighted shortest path, and connected components include pending edge overlays after `graph.apply_sync()`. Weighted shortest path fails closed while overlays are pending because pending edge mutations do not carry edge weights. ## RLS Relationship Identity Requires A Rebuild Symptom: ```text SQLSTATE 55000 DETAIL: pgGraph diagnostic: PG023 ``` pgGraph 1.1 evaluates relationship-source RLS before an edge can affect topology. That requires every projected edge to retain its source-row identity. If a compatible legacy artifact does not contain a usable identity for an RLS-active relationship mapping, pgGraph fails closed instead of treating the edge as visible. Rebuild from the authoritative PostgreSQL tables: ```sql SELECT * FROM graph.build(); ``` The replacement is published only after validation. If the rebuild fails or is cancelled, the previous published generation remains authoritative, but RLS queries that require the missing identity continue to fail closed until a successful rebuild. ## Schema Invalid Or Needs Rebuild Symptoms: ```sql SELECT schema_status, needs_rebuild, invalid_reason FROM graph.status(); ``` Fix after catalog or source schema changes: ```sql SELECT * FROM graph.registered_tables(); SELECT * FROM graph.registered_edges(); SELECT * FROM graph.build(); ``` If a registered column no longer exists, remove or update the registration. ## Build Fails With Memory Error Symptom: SQLSTATE `53200`, diagnostic `PG001`. Check: ```sql SELECT * FROM graph.estimate(); SHOW graph.memory_limit_mb; ``` Fix: ```sql ALTER SYSTEM SET graph.memory_limit_mb = 8192; SELECT pg_reload_conf(); ``` Or reduce registered graph scope. ## Query Or Maintenance Hits A Resource Limit Symptom: SQLSTATE `54000`, diagnostic `PG007`. The error names the phase, resource kind, current use, requested amount, and configured limit. Inspect the most recent completed governed operation in the same backend: ```sql SELECT * FROM graph.resource_status(); SHOW graph.query_memory_mb; SHOW graph.maintenance_memory_mb; SHOW graph.spill_disk_limit_mb; SHOW graph.query_work_limit; SHOW graph.operation_timeout_ms; ``` Reduce result cardinality, depth, wildcard range, hydration width, sync batch, or compaction range before raising a limit. If you raise a memory setting, remember that `graph.memory_limit_mb` is still the hard backend-private ceiling after the loaded graph's residency. PostgreSQL cancellation and `statement_timeout` are checked throughout long graph operations. ## Build Or Vacuum Locked Symptom: SQLSTATE `55P03`, diagnostic `PG006`. Check: ```sql SELECT pid, state, query FROM pg_stat_activity WHERE query ILIKE '%graph.build%' OR query ILIKE '%graph.vacuum%' OR query ILIKE '%graph.maintenance%'; ``` Wait for the current operation or investigate the owning session. ## Corrupt Or Incompatible Artifact Symptoms: SQLSTATE `XX001`/diagnostic `PG009`, or SQLSTATE `0A000`/diagnostic `PG011`. Fix: ```sql SELECT * FROM graph.build(); ``` If needed: ```sql SELECT graph.reset(); SELECT * FROM graph.build(); ``` ## Edge Buffer Full Symptom: diagnostic `PG008` or `PG012`, `read_only = true`, or high `edge_buffer_used`. The corresponding SQLSTATE is `54000` or `55000`. Check: ```sql SELECT edge_buffer_used, needs_vacuum, read_only, read_only_reason FROM graph.status(); ``` Fix: ```sql SELECT * FROM graph.maintenance(); ``` or: ```sql SELECT * FROM graph.vacuum(); ``` ## ACL Denied Symptom: SQLSTATE `42501`, diagnostic `PG002`. Fix for read queries: ```sql GRANT SELECT ON public.source_table TO app_role; ``` Fix for admin operations: ```sql GRANT USAGE, CREATE ON SCHEMA graph TO graph_admin; ``` ## Operational Failure Matrix Use this matrix when diagnosing complex production failures relating to jobs, quotas, sync, or storage. | Failure | Stable state | SQLSTATE / diagnostic | Visible location | Recovery action | Read impact | |---|---|---|---|---|---| | **Sync falls behind** | `sync_status = 'syncing'`, `sync_lag > 0` | `0A000` / `PG018` if the lag surfaces as an unsupported-operation guard | `graph.status().sync_lag`, `graph.status().pending_sync_rows`, `graph.jobs()` | Run `graph.run_due_jobs()` or `graph.run_job(job_id)` after confirming the source tables are healthy. | Serves the last valid generation. | | **Artifacts are missing** | `graph.projection_status().artifact_validation_state = 'full_rebuild'` | `XX001` / `PG009` | `graph.status().schema_status`, `graph.projection_status().artifact_validation_state` | Run `graph.projection_repair()` or `graph.build()` to publish a fresh artifact. | Reads fail on affected paths until rebuilt. | | **Artifact validation fails** | `graph.projection_status().artifact_validation_state = 'targeted_chunk_repair'` | `XX001` / `PG009` | `graph.projection_status().artifact_validation_state` | Run `graph.projection_repair()`; if repair cannot salvage the files, rebuild. | Reads fail on affected paths until repaired. | | **Disk is full** | `read_only_reason` indicates storage pressure | `53100` | `graph.status().read_only_reason`, `graph.job_runs()` | Free space, then rerun `graph.run_due_jobs()` or `graph.projection_repair()`. | Serves the last valid generation. | | **Compaction fails** | `graph.projection_status().artifact_validation_state = 'targeted_chunk_repair'` after a failed compaction run | `0A000` / `PG018` | `graph.projection_status().last_compaction_unix_micros`, `graph.job_runs()` | Fix the underlying artifact problem and rerun `graph.projection_repair()` or `graph.maintenance()`. | Serves the last valid generation. | | **Projection ingest fails** | `pending_durable_rows > 0` and `repair_recommended = true` | `0A000` / `PG018` | `graph.projection_status().pending_durable_rows`, `graph.projection_status().repair_recommended` | Repair the projection artifact, then rerun the ingest path. | Serves the last valid generation. | | **A job repeatedly errors** | `graph.jobs().last_status = 'retryable_failed'` or `graph.jobs().last_status = 'permanent_failed'` | `XX000` or a more specific job SQLSTATE | `graph.jobs()`, `graph.job_runs()` | Inspect the most recent run error, correct the source issue, and rerun the job. | Depends on job type. | | **A graph exceeds quota** | `graph.graph_quota_usage().exceeded = true` | `54000` / `PG019` | `graph.graph_quota_usage()` | Raise the quota or shrink graph scope/storage. | New writes, builds, or loads can be blocked. | | **Background workers unavailable** | `graph.jobs().last_status = 'queued'` | N/A | `graph.jobs()`, `graph.job_runs()` | Restore worker capacity, then run `graph.run_due_jobs()` manually. | Serves the last valid generation. | | **Schema/catalog drift** | `schema_status = 'invalid'` and `needs_rebuild = true` | `0A000` / `PG018` | `graph.status().schema_status`, `graph.status().needs_rebuild` | Run `graph.build()` for the selected graph. | Reads fail on affected paths until rebuilt. | ## Maintainer Validation If a reproducible issue requires release-class ACL, concurrency, install, or crash validation, include the public diagnostics above in the issue report. Maintainers can then select the appropriate focused gate from the [Testing And Release](../contributor_guide/testing-release) guide.