Skip to content

fix(OpenGraph): fix ID column for schema_findings table BED-7734#2538

Open
sirisjo wants to merge 1 commit intostage/v8.9.1from
BED-7734
Open

fix(OpenGraph): fix ID column for schema_findings table BED-7734#2538
sirisjo wants to merge 1 commit intostage/v8.9.1from
BED-7734

Conversation

@sirisjo
Copy link
Contributor

@sirisjo sirisjo commented Mar 23, 2026

Description

Fixes a duplicate key error that occurs during the on-start findings migration if the database had existing findings in the schema_relationship_findings table during the v8.9.0 migration.

Motivation and Context

Resolves BED-7734

Why is this change required? What problem does it solve?

How Has This Been Tested?

Reproduced the issue locally, and then ran this fix and the issue was solved.

To repro locally, run the v.8.7.0 version of the code and upload an OpenGraph schema with findings. When migrating to v8.9.0, you should encounter the error. Run the v8.9.1 migration to fix the error. The database schema_findings table should be populated with your OpenGraph findings first, and then the built-in findings.

Screenshots (optional):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Database Migrations

Checklist:

Summary by CodeRabbit

  • Chores
    • Applied a database migration that updates an internal ID sequence to align with existing records, ensuring sequence consistency with current data.

@sirisjo sirisjo self-assigned this Mar 23, 2026
@sirisjo sirisjo added bug Something isn't working dbmigration labels Mar 23, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 23, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 3d2eff0a-9083-4a00-a108-cbf85ca9915e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a SQL migration (v8.9.1.sql) that sets the schema_findings_id_seq sequence value to the maximum id in schema_findings (or 1 if empty) using setval(..., is_called => true).

Changes

Cohort / File(s) Summary
Database Migration
cmd/api/src/database/migration/migrations/v8.9.1.sql
New migration executing SELECT setval('schema_findings_id_seq', COALESCE((SELECT MAX(id) FROM schema_findings), 1), true); to update the schema_findings sequence value.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly references the bug fix for the schema_findings ID column issue, matching the main change in the SQL migration that resets the sequence.
Description check ✅ Passed The PR description covers the required sections: problem description, motivation (BED-7734), testing steps, change types, and completed checklist items.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch BED-7734

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/api/src/database/migration/migrations/v8.9.1.sql`:
- Around line 17-18: Modify the SETVAL call to handle an empty schema_findings
table by replacing MAX(id) with COALESCE(MAX(id), 0) so the sequence is set to 0
when no rows exist; update the statement using the existing sequence name
schema_findings_id_seq and table schema_findings (i.e., call
setval('schema_findings_id_seq', COALESCE(MAX(id), 0), true) FROM
schema_findings) to avoid NULL causing setval() to fail.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: ca7f9ab6-44f5-452e-8b66-264ea2141336

📥 Commits

Reviewing files that changed from the base of the PR and between 00cbd6c and af3f1ed.

📒 Files selected for processing (1)
  • cmd/api/src/database/migration/migrations/v8.9.1.sql

Comment on lines +17 to +18
-- Fix schema_findings_pkey duplicate key value violation
SELECT setval('schema_findings_id_seq', MAX(id), true) FROM schema_findings; No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Test the migration on an empty schema_findings table scenario

# Check if there are any test files that cover this migration
rg -n "v8\.9\.1|schema_findings_id_seq" --type=go --glob '*test*'

# Check for similar sequence reset patterns in other migrations
rg -n "setval.*COALESCE|setval.*MAX\(id\)" --type=sql

Repository: SpecterOps/BloodHound

Length of output: 874


🏁 Script executed:

# Check the migration execution order and schema_findings initialization
# Look at v8.9.0 to understand what triggered the need for this fix
fd -e sql -name "v8.9.0" | head -20

Repository: SpecterOps/BloodHound

Length of output: 295


🏁 Script executed:

# Search for schema_findings table creation and when it's populated
rg -n "schema_findings" --type=sql -B 2 -A 2 | head -50

Repository: SpecterOps/BloodHound

Length of output: 3822


🏁 Script executed:

# Check if there's any migration framework logic or safeguards
fd -e go -name "*migrat*" | head -20

Repository: SpecterOps/BloodHound

Length of output: 295


🌐 Web query:

PostgreSQL setval function behavior with NULL value empty table

💡 Result:

The PostgreSQL setval function requires a non-NULL bigint value as its second argument and cannot accept NULL directly. Attempting SELECT setval('seq', NULL) will raise an error like "function setval(unknown, unknown) does not exist" or a type mismatch error, as NULL lacks a specific type and the function signature expects bigint. For an empty table where MAX(id) returns NULL (common when resetting sequences after TRUNCATE or for new tables), directly passing NULL to setval fails. Instead, use COALESCE to handle NULL: SELECT setval('seq', COALESCE((SELECT MAX(id) FROM table), 0), false); This sets last_value to 0 (allowed only if minvalue <=0, else use 1 and adjust), with is_called=false so nextval returns 1. Official docs confirm setval(regclass, bigint [, boolean]) → bigint, with the second parameter being the value to set last_value to, which must be within the sequence's minvalue/maxvalue bounds (default minvalue=1 for ascending sequences created by SERIAL). Setting below minvalue errors: "setval: value X is out of bounds". To reset for empty table to start at 1: - If minvalue=1: SELECT setval('seq', 1, false); -- next nextval returns 1 - Or use ALTER SEQUENCE seq RESTART; -- equivalent to setval with is_called=false using recorded start value (usually 1) Sources confirm this behavior across versions up to 18; no direct NULL support exists.

Citations:


🏁 Script executed:

# Check the context of schema.sql - when/how is it executed?
head -50 cmd/api/src/database/migration/migrations/schema.sql

Repository: SpecterOps/BloodHound

Length of output: 1640


🏁 Script executed:

# Look at the migration framework - how are versions ordered and applied?
fd -type f -name "*.go" | xargs grep -l "migration\|Migration" | head -5

Repository: SpecterOps/BloodHound

Length of output: 235


🏁 Script executed:

# Check if there's any logic about when migrations apply or reset sequences
rg -n "schema.sql" --type=go -B 2 -A 2 | head -50

Repository: SpecterOps/BloodHound

Length of output: 1571


🏁 Script executed:

# Verify: does v8.9.0 migration actually insert data, or is schema_findings empty after v8.9.0?
cat cmd/api/src/database/migration/migrations/v8.9.0.sql

Repository: SpecterOps/BloodHound

Length of output: 8878


🏁 Script executed:

# Check migration ordering and execution - is v8.9.0/v8.9.1 only for upgrades?
rg -n "version|Version" cmd/api/src/database/migration/migrations/v8.9.0.sql | head -5

Repository: SpecterOps/BloodHound

Length of output: 116


🏁 Script executed:

# Look at how migrations are applied - check manifest or migration runner
fd -type f -name "*.go" -path "*/migration/*" | xargs grep -l "manifest\|apply\|version" | head -3

Repository: SpecterOps/BloodHound

Length of output: 235


🏁 Script executed:

# Check: does the base schema.sql have the same setval NULL issue?
# Find where setval calls on empty tables would occur
rg "SELECT setval.*MAX\(id\)" cmd/api/src/database/migration/migrations/schema.sql -B 5 -A 1 | head -40

Repository: SpecterOps/BloodHound

Length of output: 47


Handle NULL case when schema_findings table is empty.

The MAX(id) function returns NULL when the table is empty, causing setval() to fail and block the migration. This occurs when schema_relationship_findings doesn't exist (fresh installations or previously migrated systems).

Proposed fix
 -- Fix schema_findings_pkey duplicate key value violation 
-SELECT setval('schema_findings_id_seq', MAX(id), true) FROM schema_findings;
+SELECT setval('schema_findings_id_seq', COALESCE(MAX(id), 0), true) FROM schema_findings;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-- Fix schema_findings_pkey duplicate key value violation
SELECT setval('schema_findings_id_seq', MAX(id), true) FROM schema_findings;
-- Fix schema_findings_pkey duplicate key value violation
SELECT setval('schema_findings_id_seq', COALESCE(MAX(id), 0), true) FROM schema_findings;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/api/src/database/migration/migrations/v8.9.1.sql` around lines 17 - 18,
Modify the SETVAL call to handle an empty schema_findings table by replacing
MAX(id) with COALESCE(MAX(id), 0) so the sequence is set to 0 when no rows
exist; update the statement using the existing sequence name
schema_findings_id_seq and table schema_findings (i.e., call
setval('schema_findings_id_seq', COALESCE(MAX(id), 0), true) FROM
schema_findings) to avoid NULL causing setval() to fail.

@sirisjo sirisjo changed the base branch from main to stage/v8.9.1 March 23, 2026 23:25
@sirisjo sirisjo requested review from a team as code owners March 23, 2026 23:25
@sirisjo sirisjo removed request for a team March 23, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working dbmigration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant