Repository navigation
Federal AGI drops a Schedule C loss when the same person has Schedule C profit in the other SSTB category #9989
Description
Summary
When one person has a loss in self_employment_income (non-SSTB Schedule C) and a profit in sstb_self_employment_income (SSTB Schedule C), or the reverse, the loss never reaches AGI. irs_gross_income counts each category's profit on its own, but loss_ald deducts only the negative part of the person's net total_self_employment_income. A $5,000 loss next to a $5,000 profit therefore gives AGI of $5,000 and loss_ald of $0. Per the 2024 Schedule C, Schedule 1 and Form 1040, both Schedule C results go on Schedule 1 line 3, so AGI is $0.
Both pieces came from #7944, which added sstb_self_employment_income to gov.irs.gross_income.sources and switched loss_ald to total_self_employment_income. Self-employment tax is not affected: it already nets the two categories (case C below).
Reproduction
policyengine-us main at 07227ea, single filer, age 40, TX, 2024. Only the inputs listed are set.
| Case | self_employment_income |
sstb_self_employment_income |
employment_income |
irs_gross_income |
loss_ald |
self_employment_tax_ald |
adjusted_gross_income |
income_tax |
|---|---|---|---|---|---|---|---|---|
| A | -5,000 | 5,000 | 0 | 5,000 | 0 | 0 | 5,000 | 0 |
| B | 5,000 | -5,000 | 0 | 5,000 | 0 | 0 | 5,000 | 0 |
| C | -5,000 | 8,000 | 0 | 8,000 | 0 | 211.94 | 7,788.06 | -213.29 |
| D | -5,000 | 5,000 | 50,000 | 55,000 | 0 | 0 | 55,000 | 4,616 |
| E (control) | 0 | 0 | 50,000 | 50,000 | 0 | 0 | 50,000 | 4,016 |
In case C, self_employment_tax_ald of $211.94 is half the SE tax on the net $3,000 (3,000 × 0.9235 × 0.153 / 2), so the SE tax path nets the categories while the AGI path does not. Case D shows the effect on tax: the same AGI under the forms (see below) but $600 more income tax than control E.
from policyengine_us import Simulation
sim = Simulation(situation={
"people": {"p": {"age": {2024: 40},
"self_employment_income": {2024: -5_000},
"sstb_self_employment_income": {2024: 5_000}}},
"tax_units": {"tu": {"members": ["p"]}},
"households": {"h": {"members": ["p"], "state_code": {2024: "TX"}}},
})
for v in ["total_self_employment_income", "irs_gross_income",
"loss_ald", "adjusted_gross_income"]:
print(v, sim.calculate(v, 2024)[0])
# total_self_employment_income 0.0
# irs_gross_income 5000.0
# loss_ald 0.0
# adjusted_gross_income 5000.0Mechanism
irs_gross_income.py L17–L19 floors each source at zero, and sources.yaml L5–L6 lists the two Schedule C categories as separate sources:
for source in sources:
# Add positive values only - losses are deducted later.
total += not_dependent * max_(0, add(person, period, [source])) - self_employment_income
- sstb_self_employment_incomeloss_ald.py L34–L35 takes the loss from the net of both categories (total_self_employment_income adds = ["self_employment_income", "sstb_self_employment_income"]):
indiv_se_income = max_(0, person("total_self_employment_income", period))
indiv_se_loss = max_(0, -person("total_self_employment_income", period))With -5,000 and +5,000, gross income takes max_(0, -5,000) + max_(0, 5,000) = 5,000, while loss_ald takes max_(0, -(−5,000 + 5,000)) = 0. The $5,000 loss is dropped. The other business sources (farm, rental, farm rent, estate, partnership/S-corp, Form 4797 other net gain) take profit and loss from the same quantity in both places, so only the Schedule C pair is out of step.
dependent_taxable_ss_magi already nets the two categories: both are in its BUSINESS_LOSS_SOURCES, so when loss_ald is an allowed deduction it adds each one without a floor.
What the 2024 forms say
Schedule C (Form 1040) 2024, page 1, lines 31–32
31 Net profit or (loss). Subtract line 30 from line 29.
• If a profit, enter on both Schedule 1 (Form 1040), line 3, and on Schedule SE, line 2. (If you checked the box on line 1, see instructions.) Estates and trusts, enter on Form 1041, line 3.
• If a loss, you must go to line 32.
32 If you have a loss, check the box that describes your investment in this activity. See instructions.
• If you checked 32a, enter the loss on both Schedule 1 (Form 1040), line 3, and on Schedule SE, line 2. […]
Instructions for Schedule C (Form 1040) 2024, page C-3, "Line A"
If you owned more than one business, complete a separate Schedule C for each business.
Instructions for Schedule C (Form 1040) 2024, page C-15, "Line 31" › "Reporting your net profit or loss"
Individuals. Enter your net profit or loss on line 31 and include it on Schedule 1 (Form 1040), line 3. Also, include your net profit or loss on Schedule SE, line 2.
Schedule 1 (Form 1040) 2024, page 1, Part I — Additional Income
3 Business income or (loss). Attach Schedule C
10 Combine lines 1 through 7 and 9. This is your additional income. Enter here and on Form 1040, 1040-SR, or 1040-NR, line 8
Form 1040 (2024), page 1
8 Additional income from Schedule 1, line 10
9 Add lines 1z, 2b, 3b, 4b, 5b, 6b, 7, and 8. This is your total income
10 Adjustments to income from Schedule 1, line 26
11 Subtract line 10 from line 9. This is your adjusted gross income
26 U.S.C. § 62(a)(1) (LII)
For purposes of this subtitle, the term "adjusted gross income" means, in the case of an individual, gross income minus the following deductions: (1) Trade and business deductions The deductions allowed by this chapter (other than by part VII of this subchapter) which are attributable to a trade or business carried on by the taxpayer, if such trade or business does not consist of the performance of services by the taxpayer as an employee.
For context only (this governs SE tax, which PE already nets correctly, not AGI):
Instructions for Schedule SE (Form 1040) 2024, pages SE-2–SE-3, "More Than One Business"
If you had two or more businesses subject to SE tax, your net earnings from self-employment are the combined net earnings from all of your businesses. If you had a loss in one business, it reduces the income from another. Figure the combined SE tax on one Schedule SE.
The SSTB/non-SSTB split is a § 199A classification; total_self_employment_income documents both variables as "Schedule C income". A person with amounts in both categories has two businesses and so two Schedules C (Line A), and both line 31 results go to Schedule 1 line 3. PE applies no at-risk (§ 465) or passive-activity (§ 469) limit to self_employment_income or sstb_self_employment_income, so the repro corresponds to a loss that is fully at risk (box 32a) and not passive.
Expected values (from the forms above)
- Case A: Schedule C (non-SSTB) line 31 = (5,000); Schedule C (SSTB) line 31 = 5,000. Schedule 1 line 3 = 0, line 10 = 0. Schedule SE line 2 = 0, so no SE tax and no SE-tax adjustment. Form 1040 line 8 = 0, line 9 = 0, line 11 AGI = 0.
- Case B: the same with the signs swapped. AGI = 0.
- Case D: case A plus $50,000 wages on line 1z. Schedule 1 line 3 = 0, so Form 1040 line 9 = 50,000, line 10 = 0, line 11 AGI = 50,000 — the same AGI as control E.
Proposed fix
Deduct each Schedule C category's loss on its own in loss_ald, which matches how irs_gross_income counts each category's profit on its own:
- indiv_se_income = max_(0, person("total_self_employment_income", period))
- indiv_se_loss = max_(0, -person("total_self_employment_income", period))
+ # irs_gross_income counts each Schedule C category's profit on its
+ # own, so each category's loss is deducted on its own here.
+ non_sstb_se = person("self_employment_income", period)
+ sstb_se = person("sstb_self_employment_income", period)
+ indiv_se_income = max_(0, non_sstb_se) + max_(0, sstb_se)
+ indiv_se_loss = max_(0, -non_sstb_se) + max_(0, -sstb_se)The § 461(l) cap is unaffected for the same net amount: with business profit I, loss L and threshold T, the allowed net is I − min(L, I + T) = max(I − L, −T) whether the two categories are netted first or not.
Open PRs #9890 and #9762 move this block into a new limited_business_loss.py with the same total_self_employment_income lines. Whichever merges first, the same change belongs in that file.
An alternative is to replace the two entries in gov.irs.gross_income.sources with total_self_employment_income. That changes the zero floor for about ten other consumers of the list (medicaid_irs_gross_income, dependent_gross_income, taxable_ss_magi, taxable_uc_agi, student_loan_interest_ald_magi, capped_qualified_tuition_expenses_ald, the CRFB and tax-exempt reforms) and needs BUSINESS_LOSS_SOURCES in dependent_taxable_ss_magi.py updated, so the loss_ald change is the smaller fix.
Tests
For tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/self_employment_income.yaml. Expected values come from the form arithmetic above.
- name: Non-SSTB Schedule C loss offsets SSTB Schedule C profit in AGI
period: 2024
input:
self_employment_income: -5_000
sstb_self_employment_income: 5_000
output:
adjusted_gross_income: 0
- name: SSTB Schedule C loss offsets non-SSTB Schedule C profit in AGI
period: 2024
input:
self_employment_income: 5_000
sstb_self_employment_income: -5_000
output:
adjusted_gross_income: 0
- name: Offsetting Schedule C results leave AGI equal to wages
period: 2024
input:
employment_income: 50_000
self_employment_income: -5_000
sstb_self_employment_income: 5_000
output:
adjusted_gross_income: 50_000Local check against main at 07227ea: all three tests fail without the fix and pass with it.
Related
- Add SSTB self-employment income variable and split QBID by category #7944 — added
sstb_self_employment_incometo the gross income sources andtotal_self_employment_incometoloss_ald. - Give each spouse their own above-the-line deductions in per-person AGI #9890, Count capital gains once in Arizona property tax credit income #9762 — open; move the
loss_aldbusiness-loss block tolimited_business_loss.py. - Partnership/S-corp losses not included in AGI; missing Section 461(l) excess business loss limitation #7015 (fixed by Implement IRC § 461(l) excess business loss limitation #8050) and S-Corp/partnership losses excluded from AGI due to max(0,...) in irs_gross_income #7461 (closed) — earlier reports of partnership/S-corp losses dropped by the
max_(0, ...)floor inirs_gross_income; Implement IRC § 461(l) excess business loss limitation #8050 added theloss_aldpattern that this issue relies on. - policyengine-taxsim maps TAXSIM
psemp/ssempandpbusinc/sbusinctoself_employment_income, andpprofinc/sprofinctosstb_self_employment_income, so TAXSIM records with a loss in one group and a profit in the other hit this.
Activity
Treat Schedule C categories separately in the loss invariant reference
Offset SSTB and non-SSTB Schedule C results in federal AGI (#9995)