Tencent/WeKnora · error

%s

Error message

%s

What it means

ValidateAndSecureSQL validates a SQL string and, if the validation result is invalid, returns an error whose message is the first SQLValidationError's Message (or the generic 'SQL validation failed'). The library throws this because it refuses to secure or return SQL that failed its policy checks (not SELECT, disallowed tables, injection risk, multiple statements, etc.). The returned *SQLValidationResult contains the full Errors list for diagnosis.

Source

Thrown at internal/utils/inject.go:859

		}
	}

	return result, validationResult
}

// ValidateAndSecureSQL validates SQL and returns a secured version with tenant isolation
// This is a convenience function that combines validation and SQL rewriting
func ValidateAndSecureSQL(sql string, opts ...SQLValidationOption) (string, *SQLValidationResult, error) {
	// Parse and validate
	_, validationResult := ValidateSQL(sql, opts...)

	// If validation failed, return error
	if !validationResult.Valid {
		errMsg := "SQL validation failed"
		if len(validationResult.Errors) > 0 {
			errMsg = validationResult.Errors[0].Message
		}
		return "", validationResult, fmt.Errorf("%s", errMsg)
	}

	// Find validator config to check if tenant injection is enabled
	validator := &sqlValidator{
		tablesWithTenantID:  make(map[string]bool),
		tablesWithDeletedAt: make(map[string]bool),
	}
	for _, opt := range opts {
		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

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Inspect the returned validationResult.Errors[0] (Type and Details) to see which phase failed
  2. Ensure the query is a single SELECT statement over tables registered via WithAllowedTables
  3. If you control the query construction, fix the SQL itself rather than bypassing validation
  4. If validation is too strict for a legitimate query, adjust the relevant options (e.g. disable checkInjectionRisk) knowingly

Example fix

// before
secured, res, err := utils.ValidateAndSecureSQL(userSQL)
if err != nil { return err }
// after
secured, res, err := utils.ValidateAndSecureSQL(userSQL,
    utils.WithAllowedTables([]string{"knowledge_bases", "documents"}))
if err != nil {
    for _, e := range res.Errors {
        log.Printf("SQL rejected [%s]: %s (%s)", e.Type, e.Message, e.Details)
    }
    return fmt.Errorf("query rejected: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

func preCheck(sql string) error {
    t := strings.TrimSpace(sql)
    if t == "" || !strings.HasPrefix(strings.ToUpper(t), "SELECT") {
        return fmt.Errorf("only single SELECT statements are supported")
    }
    if strings.ContainsAny(sql, ";\x00") {
        return fmt.Errorf("multiple statements or invalid characters")
    }
    return nil
}

Type guard

func hasValidationErrors(res *utils.SQLValidationResult) bool {
    return res != nil && len(res.Errors) > 0
}

Try / catch

secured, res, err := utils.ValidateAndSecureSQL(sql)
if err != nil {
    if hasValidationErrors(res) {
        return fmt.Errorf("query rejected (%s): %s",
            res.Errors[0].Type, res.Errors[0].Details)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ValidateAndSecureSQL with SQL that fails any validation phase: input contains a null byte, is too short/long, is not a single SELECT statement, references a table not in allowedTables, or matches injection-risk patterns in the WHERE clause.

Common situations: Developers passing user-supplied or dynamically built SQL that uses non-SELECT statements; forgetting to register a table via WithAllowedTables; queries with suspicious string concatenation in WHERE clauses; accidentally passing empty or truncated SQL.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/757db5bb921c743b. Report an issue: GitHub.