{"record":{"id":"eb1eeaacd2c5b992","repo":"bytebase/bytebase","slug":"failed-to-get-trigger-comments","errorCode":null,"errorMessage":"failed to get trigger comments","messagePattern":"failed to get trigger comments","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/db/oracle/sync.go","lineNumber":235,"sourceCode":"\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, util.FormatErrorWithQuery(err, query)\n\t}\n\tif err := rows.Close(); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to close rows\")\n\t}\n\n\treturn result, nil\n}\n\nfunc getTriggers(txn *sql.Tx, schemaName string) (map[db.TableKey][]*storepb.TriggerMetadata, map[db.TableKey][]*storepb.TriggerMetadata, error) {\n\ttableTriggerMap := make(map[db.TableKey][]*storepb.TriggerMetadata)\n\tviewTriggerMap := make(map[db.TableKey][]*storepb.TriggerMetadata)\n\n\t// Get trigger comments\n\ttriggerCommentMap, err := getTriggerComments(txn, schemaName)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrapf(err, \"failed to get trigger comments\")\n\t}\n\n\tquery := fmt.Sprintf(`\n\t\tSELECT TRIGGER_NAME, TABLE_NAME, DESCRIPTION, TRIGGER_BODY, BASE_OBJECT_TYPE, TRIGGER_TYPE, TRIGGERING_EVENT\n\t\tFROM sys.all_triggers\n\t\tWHERE OWNER = '%s' AND TABLE_NAME is NOT NULL AND (BASE_OBJECT_TYPE = 'TABLE' OR BASE_OBJECT_TYPE = 'VIEW')\n\t\tORDER BY TRIGGER_NAME`, schemaName)\n\n\tslog.Debug(\"running get triggers query\")\n\trows, err := txn.Query(query)\n\tif err != nil {\n\t\treturn nil, nil, util.FormatErrorWithQuery(err, query)\n\t}\n\tdefer rows.Close()\n\n\tfor rows.Next() {\n\t\tvar triggerName, tableName, description, triggerBody, baseObjectType, triggerType, triggeringEvent sql.NullString\n\t\tif err := rows.Scan(&triggerName, &tableName, &description, &triggerBody, &baseObjectType, &triggerType, &triggeringEvent); err != nil {","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/db/oracle/sync.go#L217-L253","documentation":"getTriggers failed while fetching trigger comments from the Oracle catalog. getTriggerComments queries sys triggers/comments views (e.g. all_triggers with description/body) and any error is wrapped as 'failed to get trigger comments'. The whole trigger sync — and thus SyncDBSchema — aborts.","triggerScenarios":"SyncDBSchema on a schema with triggers where the trigger-comment catalog query fails: missing privileges on the trigger catalog views, an invalid schemaName (empty/quoted wrongly interpolated into the query), or a mid-query connection failure.","commonSituations":"Sync user without grants on all_triggers/all_source; schema name containing characters that break the fmt.Sprintf-interpolated WHERE OWNER = '%s' clause; connection drop during trigger scan.","solutions":["Inspect the wrapped inner error (includes the query) and run it manually as the sync user","Grant SELECT on sys.all_triggers and sys.all_source to the sync user","Verify the configured schemaName is a valid, correctly-cased Oracle username","Retry if the inner error indicates a transient connection problem"],"exampleFix":"// before\n-- query interpolated as WHERE OWNER = 'my schema'\n// after — use a valid, unquoted schema identifier in the instance config\n-- GRANT SELECT ON sys.all_triggers TO sync_user;","handlingStrategy":"validation","validationCode":"var n int\nif err := db.QueryRow(\"SELECT COUNT(*) FROM sys.all_triggers WHERE ROWNUM = 1\").Scan(&n); err != nil {\n    // grant SELECT ON sys.all_triggers before running sync\n}\n// also validate schemaName is a plain Oracle identifier\nif !regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_$#]*$`).MatchString(schemaName) { /* reject */ }","typeGuard":"func validOracleIdentifier(s string) bool {\n    re := regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_$#]{0,29}$`)\n    return re.MatchString(s)\n}","tryCatchPattern":"tableTriggers, viewTriggers, err := getTriggers(txn, schemaName)\nif err != nil {\n    if isPrivilegeError(err) { return fmt.Errorf(\"grant SELECT on trigger catalog views: %w\", err) }\n    return err\n}","preventionTips":["Grant trigger catalog privileges to the sync user at provisioning time","Validate the schema name is a legal Oracle identifier before interpolation","Prefer bind parameters over fmt.Sprintf for identifiers where possible"],"tags":["oracle","schema-sync","triggers","database-query-failed"],"backgroundTag":"database-query-failed","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}