Tencent/WeKnora · error
failed to normalize SQL: %v
Error message
failed to normalize SQL: %v
What it means
After a successful pg_query.Parse, ValidateAndSecureSQL calls pg_query.Deparse to regenerate normalized SQL text from the parse tree before injecting security conditions. If Deparse fails (a protobuf-to-SQL serialization failure), this error is returned. This is rare and usually indicates a parse-tree feature the deparser cannot render.
Source
Thrown at internal/utils/inject.go:886
opt(validator)
}
// If no SQL rewriting is enabled, return original SQL
if !validator.enableTenantInjection && !validator.enableSoftDeleteInjection && !validator.enableHiddenKBFilter &&
!validator.enableChunkEnabledFilter && !validator.enableSearchScopeFilter {
return sql, validationResult, nil
}
// Parse again to get normalized SQL
result, err := pg_query.Parse(sql)
if err != nil {
return "", validationResult, fmt.Errorf("failed to parse SQL: %v", err)
}
// Normalize SQL
normalizedSQL, err := pg_query.Deparse(result)
if err != nil {
return "", validationResult, fmt.Errorf("failed to normalize SQL: %v", err)
}
// Build table→alias map from parse tree (respects SQL aliases like "kb", "k")
tablesInQuery := extractTableAliasMap(result)
// Inject tenant conditions
securedSQL := validator.injectTenantConditions(normalizedSQL, tablesInQuery)
// Inject deleted_at IS NULL conditions
securedSQL = validator.injectSoftDeleteConditions(securedSQL, tablesInQuery)
// Inject hidden KB filter (exclude is_temporary = true knowledge bases)
securedSQL = validator.injectHiddenKBFilter(securedSQL, tablesInQuery)
// Exclude disabled chunks from model-visible query results.
securedSQL = validator.injectChunkEnabledFilter(securedSQL, tablesInQuery)
// Inject search scope filter (restrict to allowed KBs and knowledges)
securedSQL = validator.injectSearchScopeConditions(securedSQL, tablesInQuery)
return securedSQL, validationResult, nil
}View on GitHub (pinned to 988cbb0330)
Solutions
- Upgrade github.com/pgquery/pgquery-go to the latest version
- Simplify or rewrite the query using widely supported PostgreSQL syntax
- Check the pg_query-go issue tracker for known Deparse limitations
- Restructure the query so the deparser can render it
Example fix
// before (unrenderable syntax) q := "SELECT * FROM t LIMIT ALL OFFSET NULL" // after q := "SELECT * FROM t OFFSET 0"
Defensive patterns
Strategy: fallback
Try / catch
secured, _, err := utils.ValidateAndSecureSQL(sql)
if err != nil && strings.Contains(err.Error(), "failed to normalize SQL") {
// fail closed: never fall back to unsecured SQL for tenant isolation
return nil, fmt.Errorf("cannot secure query: %w", err)
} Prevention
- Keep github.com/pgquery/pgquery-go at the latest release so parser and deparser versions match
- Avoid exotic/newest PostgreSQL syntax in queries meant for rewriting
- Add a CI test that deparses every query template used in production
- On deparse failure, fail closed rather than executing unsecured SQL
When it happens
Trigger: pg_query.Deparse failing on a successfully parsed statement — typically exotic or very new PostgreSQL syntax the embedded deparser cannot render back to text, or library version bugs.
Common situations: Using a pg_query-go version whose deparser lags the parser; queries with newer PostgreSQL grammar that parse but cannot be deparsed.
Related errors
- failed to parse SQL: %v
- compound queries (UNION/INTERSECT/EXCEPT) are not allowed
- WITH clause (CTEs) is not allowed
- SELECT INTO is not allowed
- locking clauses (FOR UPDATE, etc.) are not allowed
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/7e5c45bac81bda1d.
Report an issue: GitHub.