googleapis/mcp-toolbox · error

dataset-level operations like '%s %s' are not allowed when d

Error message

dataset-level operations like '%s %s' are not allowed when dataset restrictions are in place

What it means

Under dataset restrictions, parseSQL rejects dataset/schema-level DDL (CREATE/ALTER/DROP SCHEMA or DATASET) because such operations act on entire datasets and cannot be validated against an allowed-tables analysis. This prevents a restricted user from creating, modifying, or deleting whole datasets.

Source

Thrown at internal/tools/bigquery/bigquerycommon/table_name_parser.go:281

					case "call":
						return 0, fmt.Errorf("CALL is not allowed when dataset restrictions are in place, as the called procedure's contents cannot be safely analyzed")
					case "immediate":
						if lastToken == "execute" {
							return 0, fmt.Errorf("EXECUTE IMMEDIATE is not allowed when dataset restrictions are in place, as its contents cannot be safely analyzed")
						}
					case "procedure", "function":
						if lastToken == "create" || lastToken == "create or replace" {
							return 0, fmt.Errorf("unanalyzable statements like '%s %s' are not allowed", strings.ToUpper(lastToken), strings.ToUpper(keyword))
						}
					case verbCreate, verbAlter, verbDrop, verbSelect, verbInsert, verbUpdate, verbDelete, verbMerge:
						if statementVerb == "" {
							statementVerb = keyword
						}
					}

					if statementVerb == verbCreate || statementVerb == verbAlter || statementVerb == verbDrop {
						if keyword == "schema" || keyword == "dataset" {
							return 0, fmt.Errorf("dataset-level operations like '%s %s' are not allowed when dataset restrictions are in place", strings.ToUpper(statementVerb), strings.ToUpper(keyword))
						}
					}

					if _, ok := tableFollowsKeywords[keyword]; ok {
						expectingTable = true
						lastTableKeyword = keyword
					} else if _, ok := tableContextExitKeywords[keyword]; ok {
						expectingTable = false
						lastTableKeyword = ""
					}
					if lastToken == "create" && keyword == "or" {
						lastToken = "create or"
					} else if lastToken == "create or" && keyword == "replace" {
						lastToken = "create or replace"
					} else {
						lastToken = keyword
					}
				} else if len(parts) >= 2 {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Remove the dataset-level DDL statement from the restricted query path
  2. Perform dataset create/alter/drop with an admin credential outside dataset restrictions
  3. Pre-create the dataset manually, then run only table-level statements through the restricted tool

Example fix

// before
CREATE SCHEMA proj.new_ds;
SELECT * FROM proj.ds.t;
// after
-- create dataset via admin tooling first, then:
SELECT * FROM proj.ds.t;
Defensive patterns

Strategy: validation

Validate before calling

verbs := []string{"CREATE", "ALTER", "DROP"}
objects := []string{"SCHEMA", "DATASET"}
u := strings.ToUpper(sql)
for _, v := range verbs {
    for _, o := range objects {
        if strings.Contains(u, v+" "+o) {
            return fmt.Errorf("query rejected: %s %s requires unrestricted access", v, o)
        }
    }
}

Try / catch

_, err := parser.Parse(sql)
if err != nil && strings.Contains(err.Error(), "dataset-level operations") {
    // escalate to an admin workflow or reject with a clear message
    return err
}

Prevention

When it happens

Trigger: Submitting a statement whose verb is CREATE, ALTER, or DROP followed by the keyword 'schema' or 'dataset' through TableParser/parseSQL with dataset restrictions enabled.

Common situations: Migration scripts that create or drop datasets; automated jobs doing CREATE SCHEMA IF NOT EXISTS; users confusing dataset-scoped admin work with normal queries.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/8da5661462cb640c. Report an issue: GitHub.