Skip to content

fix: clean up temporary file after table maintenance job execution#245

Open
iemejia wants to merge 3 commits into
microsoft:mainfrom
iemejia:fix/cleanup-temp-file-table-maintenance
Open

fix: clean up temporary file after table maintenance job execution#245
iemejia wants to merge 3 commits into
microsoft:mainfrom
iemejia:fix/cleanup-temp-file-table-maintenance

Conversation

@iemejia

@iemejia iemejia commented Jun 7, 2026

Copy link
Copy Markdown

Summary

The table maintenance command (fab tables optimize / fab tables vacuum) created a temporary file via NamedTemporaryFile(delete=False) to pass job configuration to the job runner, but never removed it after the job completed. The temp file persisted in the system temp directory indefinitely on every invocation.

Problem

# Before: temp file created but never cleaned up
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
    with open(temp_file.name, "w") as fp:
        json.dump(_config, fp)
    args.input = temp_file.name
    jobs.run_command(args)  # temp file left on disk after this returns

Each invocation of the table maintenance command left an orphaned file in the system temp directory (/tmp/ on Linux, %TEMP% on Windows). Over time, this accumulated files containing table maintenance job configuration (table names, schema names, maintenance parameters).

CWE-459: Incomplete Cleanup

Fix

Wrap the job execution in a try/finally block to ensure os.unlink() is called, removing the temp file even if the job fails with an exception.

# After: temp file always cleaned up
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
    with open(temp_file.name, "w") as fp:
        json.dump(_config, fp)
    args.input = temp_file.name
    try:
        jobs.run_command(args)
    finally:
        os.unlink(temp_file.name)

Tests

3 new tests:

  • test_exec_command_cleans_up_temp_file — verifies the temp file is removed after successful execution
  • test_exec_command_cleans_up_temp_file_on_error — verifies the temp file is removed even when the job raises an exception
  • test_exec_command_writes_correct_config_to_temp_file — verifies the config content (table name, schema, parameters) is written correctly

All existing tests pass (488 total).

The table maintenance command created a temporary file with
NamedTemporaryFile(delete=False) to pass job configuration, but never
removed it after the job completed. The temp file persisted in the
system temp directory indefinitely on every invocation.

Wrap the job execution in a try/finally block to ensure os.unlink()
is called, removing the temp file even if the job fails.

CWE-459: Incomplete Cleanup
Copilot AI review requested due to automatic review settings June 7, 2026 12:23
@iemejia iemejia requested a review from a team as a code owner June 7, 2026 12:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds robust cleanup for the temporary job config file used by fab tables opt, and introduces tests to ensure the temp file is removed in both success and failure scenarios.

Changes:

  • Ensure the temp config file is always deleted via try/finally in exec_command.
  • Add tests validating temp-file cleanup on success and on error.
  • Add a test validating the written temp config contents match expected job configuration.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/fabric_cli/commands/tables/fab_tables_opt.py Ensures temp config file is unlinked even when jobs.run_command raises.
tests/test_core/test_fab_tables_opt.py Adds coverage for temp file cleanup and correct config serialization.

Comment on lines +30 to +33
try:
jobs.run_command(args)
finally:
os.unlink(temp_file.name)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed. Wrapped with contextlib.suppress(OSError) (broadened from FileNotFoundError to also cover PermissionError on Windows).

Comment thread tests/test_core/test_fab_tables_opt.py Outdated
Comment on lines +69 to +72
try:
fab_tables_opt.exec_command(args)
except RuntimeError:
pass

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed. Replaced with pytest.raises(RuntimeError, match="Job failed") so the test fails if the exception is not thrown.

Copilot AI review requested due to automatic review settings June 7, 2026 12:38
@iemejia iemejia force-pushed the fix/cleanup-temp-file-table-maintenance branch from 8709239 to b5a3394 Compare June 7, 2026 12:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment on lines +27 to +35
args.configuration = None
args.input = temp_file.name
args.params = None
jobs.run_command(args)

try:
jobs.run_command(args)
finally:
with contextlib.suppress(FileNotFoundError):
os.unlink(temp_file.name)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed. Moved job execution and cleanup outside the with tempfile.NamedTemporaryFile block so the file handle is closed before os.unlink. Captured the path as temp_path = temp_file.name before exiting the with block.

…suppress OSError

Move job execution outside the NamedTemporaryFile with block so the
file handle is closed before os.unlink, which is required on Windows.
Broaden suppression to OSError (covers PermissionError on Windows too).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Table maintenance commands leave orphaned temporary files on disk

2 participants